{
  "aboutHtml": "<p>Qwen-Audio-3.0-Realtime-Plus เป็นโมเดลของ Alibaba สำหรับสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ ตอบด้วยเสียงและข้อความ และรองรับการสนทนาโต้ตอบด้วยจังหวะรับส่งคำพูดที่เป็นธรรมชาติ สามารถส่งและรับเสียงเป็นส่วน ๆ ได้ การโต้ตอบจึงดำเนินต่อไปได้ระหว่างการสนทนา</p><h4>เมื่อคู่สนทนาพูดจบความคิด</h4><p>มีหลายวิธีในการตรวจจับจุดสิ้นสุดของการพูดแต่ละครั้ง ได้แก่ ตรวจจากกิจกรรมเสียง ตรวจจากความสมบูรณ์ของความหมาย และควบคุมอย่างชัดเจน ในระบบของผู้ผลิตต้องเลือกโหมดก่อนส่งเสียงครั้งแรก หากต้องการเปลี่ยนหลังเริ่มสนทนาแล้ว ต้องสร้างการเชื่อมต่อใหม่ การรองรับการควบคุมนี้ขึ้นอยู่กับวิธีที่เลือกใช้ โหมดตรวจความหมายคำนึงถึงการหยุดเว้นช่วงและคำที่ใช้คั่นระหว่างคิด การลังเลสั้น ๆ จึงไม่จำเป็นต้องหมายความว่าผู้ใช้พูดจบความคิดแล้ว เสียงพูดใหม่ของผู้ใช้สามารถขัดจังหวะคำตอบที่กำลังสร้าง เพื่อให้การสนทนาดำเนินต่อโดยคำนึงถึงคำพูดถัดไป ในโหมดตรวจความหมายสามารถใช้ตัวอย่างเสียงของคู่สนทนาที่เลือกเป็นแนวทางในการรู้จำ เพื่อลดการรบกวนจากเสียงผู้อื่นและเสียงพื้นหลัง</p><p>คำสั่งกำหนดบทบาทของผู้ช่วยและสไตล์การสื่อสาร การถ่ายทอดด้วยเสียงสามารถปรับตามน้ำเสียง จังหวะ และอารมณ์ เวอร์ชัน 3.0 มีเสียงระบบห้าเสียงและเสียงที่สร้างจากตัวอย่างเสียงพูด โมเดลรองรับ 11 ภาษา รวมถึงภาษารัสเซีย ตลอดจนรูปแบบภาษาถิ่นจีนที่ผู้ผลิตระบุ ในระบบของผู้ผลิตต้องกำหนดเสียงเมื่ออัปเดตการตั้งค่าเซสชันครั้งแรก การส่งเสียงใหม่ภายหลังในการสนทนาเดียวกันจะถูกละเลย การตั้งค่าเหล่านี้ต้องได้รับการรองรับจากวิธีเรียกใช้ที่เลือก</p><h4>เครื่องมือและประวัติการสนทนา</h4><p>รองรับการเรียกฟังก์ชัน โมเดลระบุการกระทำที่ต้องการ จากนั้นแอปพลิเคชันที่เชื่อมต่อจะดำเนินการและส่งผลกลับเข้าบทสนทนา ทำให้สามารถสนทนาโดยอ้างอิงข้อมูลจริง และดำเนินต่อหลังทำรายการแล้ว ผู้ช่วยเสียงสามารถใช้ผลจากเครื่องมือเป็นข้อมูลอ้างอิงพร้อมรักษาบริบทของการสนทนา ความสามารถของผู้ผลิตยังรวมถึงการค้นหาเว็บในตัว หากวิธีที่เลือกใช้รองรับ แต่ไม่สามารถเปิดการค้นหาเว็บและการเรียกฟังก์ชันพร้อมกันในเซสชันเดียวได้</p><p>ประวัติการสนทนามี 20 รอบโดยค่าเริ่มต้น และกำหนดได้ตั้งแต่หนึ่งถึง 50 รอบ เสียงที่สะสมไว้มีขีดจำกัด 300 วินาที เมื่อเกินขีดจำกัด ระบบจะลบส่วนเก่าของประวัติออก ข้อจำกัดนี้ต่างจากระยะเวลาของคำพูดแต่ละครั้ง เพราะประวัติเป็นตัวกำหนดว่าข้อมูลก่อนหน้านี้ส่วนใดยังใช้ได้เมื่อสนทนาต่อ</p><h4>บริบทข้อความและเสียง</h4><p>ขนาดบริบทตามข้อกำหนดคือ 40 960 โทเคน ความยาวอินพุตสูงสุดคือ 16 384 โทเคน และเอาต์พุตสูงสุด 8192 โทเคน โหมดใช้เหตุผลระบุขีดจำกัดอินพุตและเอาต์พุตเท่ากัน โดยมีขีดจำกัดสายการให้เหตุผลแยกต่างหากที่ 1024 โทเคน</p><p>เสียงแบบสตรีมใช้ PCM หนึ่งช่องสัญญาณแบบ 16 บิต โดยอินพุตมีอัตรา 16 kHz และเอาต์พุต 24 kHz ข้อความและข้อมูลเสียงอยู่ในบทสนทนาเดียวกัน สำหรับโมเดลนี้โดยเฉพาะ ยังไม่มีการระบุอินพุตภาพหรือเอาต์พุตภาพ ความเชี่ยวชาญของโมเดลคือเสียงพูด ข้อความ และการโต้ตอบด้วยเสียง</p>",
  "aboutText": "Qwen-Audio-3.0-Realtime-Plus เป็นโมเดลของ Alibaba สำหรับสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ ตอบด้วยเสียงและข้อความ และรองรับการสนทนาโต้ตอบด้วยจังหวะรับส่งคำพูดที่เป็นธรรมชาติ สามารถส่งและรับเสียงเป็นส่วน ๆ ได้ การโต้ตอบจึงดำเนินต่อไปได้ระหว่างการสนทนา\n\n### เมื่อคู่สนทนาพูดจบความคิด\n\nมีหลายวิธีในการตรวจจับจุดสิ้นสุดของการพูดแต่ละครั้ง ได้แก่ ตรวจจากกิจกรรมเสียง ตรวจจากความสมบูรณ์ของความหมาย และควบคุมอย่างชัดเจน ในระบบของผู้ผลิตต้องเลือกโหมดก่อนส่งเสียงครั้งแรก หากต้องการเปลี่ยนหลังเริ่มสนทนาแล้ว ต้องสร้างการเชื่อมต่อใหม่ การรองรับการควบคุมนี้ขึ้นอยู่กับวิธีที่เลือกใช้ โหมดตรวจความหมายคำนึงถึงการหยุดเว้นช่วงและคำที่ใช้คั่นระหว่างคิด การลังเลสั้น ๆ จึงไม่จำเป็นต้องหมายความว่าผู้ใช้พูดจบความคิดแล้ว เสียงพูดใหม่ของผู้ใช้สามารถขัดจังหวะคำตอบที่กำลังสร้าง เพื่อให้การสนทนาดำเนินต่อโดยคำนึงถึงคำพูดถัดไป ในโหมดตรวจความหมายสามารถใช้ตัวอย่างเสียงของคู่สนทนาที่เลือกเป็นแนวทางในการรู้จำ เพื่อลดการรบกวนจากเสียงผู้อื่นและเสียงพื้นหลัง\n\nคำสั่งกำหนดบทบาทของผู้ช่วยและสไตล์การสื่อสาร การถ่ายทอดด้วยเสียงสามารถปรับตามน้ำเสียง จังหวะ และอารมณ์ เวอร์ชัน 3.0 มีเสียงระบบห้าเสียงและเสียงที่สร้างจากตัวอย่างเสียงพูด โมเดลรองรับ 11 ภาษา รวมถึงภาษารัสเซีย ตลอดจนรูปแบบภาษาถิ่นจีนที่ผู้ผลิตระบุ ในระบบของผู้ผลิตต้องกำหนดเสียงเมื่ออัปเดตการตั้งค่าเซสชันครั้งแรก การส่งเสียงใหม่ภายหลังในการสนทนาเดียวกันจะถูกละเลย การตั้งค่าเหล่านี้ต้องได้รับการรองรับจากวิธีเรียกใช้ที่เลือก\n\n### เครื่องมือและประวัติการสนทนา\n\nรองรับการเรียกฟังก์ชัน โมเดลระบุการกระทำที่ต้องการ จากนั้นแอปพลิเคชันที่เชื่อมต่อจะดำเนินการและส่งผลกลับเข้าบทสนทนา ทำให้สามารถสนทนาโดยอ้างอิงข้อมูลจริง และดำเนินต่อหลังทำรายการแล้ว ผู้ช่วยเสียงสามารถใช้ผลจากเครื่องมือเป็นข้อมูลอ้างอิงพร้อมรักษาบริบทของการสนทนา ความสามารถของผู้ผลิตยังรวมถึงการค้นหาเว็บในตัว หากวิธีที่เลือกใช้รองรับ แต่ไม่สามารถเปิดการค้นหาเว็บและการเรียกฟังก์ชันพร้อมกันในเซสชันเดียวได้\n\nประวัติการสนทนามี 20 รอบโดยค่าเริ่มต้น และกำหนดได้ตั้งแต่หนึ่งถึง 50 รอบ เสียงที่สะสมไว้มีขีดจำกัด 300 วินาที เมื่อเกินขีดจำกัด ระบบจะลบส่วนเก่าของประวัติออก ข้อจำกัดนี้ต่างจากระยะเวลาของคำพูดแต่ละครั้ง เพราะประวัติเป็นตัวกำหนดว่าข้อมูลก่อนหน้านี้ส่วนใดยังใช้ได้เมื่อสนทนาต่อ\n\n### บริบทข้อความและเสียง\n\nขนาดบริบทตามข้อกำหนดคือ 40 960 โทเคน ความยาวอินพุตสูงสุดคือ 16 384 โทเคน และเอาต์พุตสูงสุด 8192 โทเคน โหมดใช้เหตุผลระบุขีดจำกัดอินพุตและเอาต์พุตเท่ากัน โดยมีขีดจำกัดสายการให้เหตุผลแยกต่างหากที่ 1024 โทเคน\n\nเสียงแบบสตรีมใช้ PCM หนึ่งช่องสัญญาณแบบ 16 บิต โดยอินพุตมีอัตรา 16 kHz และเอาต์พุต 24 kHz ข้อความและข้อมูลเสียงอยู่ในบทสนทนาเดียวกัน สำหรับโมเดลนี้โดยเฉพาะ ยังไม่มีการระบุอินพุตภาพหรือเอาต์พุตภาพ ความเชี่ยวชาญของโมเดลคือเสียงพูด ข้อความ และการโต้ตอบด้วยเสียง",
  "editorialOverlay": {
    "copy_fields": null,
    "copy_sha256": null,
    "copy_source": null,
    "html_sha256": "7da6f049272152b5291067a70c186403ef166c5a9e36700d04df0b978538ef33",
    "module_sha256": "ee9dc1c50b1e6a8fb7fa062030fcb4646b9aaaeb08be513b723a5a92a7290f06",
    "raw_model_unchanged": true,
    "schema": "ailoot-native-model-editorial-v1"
  },
  "locale": "th",
  "methods": [
    {
      "html": "<div class=\"sheet-head\"><span class=\"mav\" aria-hidden=\"true\">Al</span><h2 id=\"sheet-title\">qwen-audio-3.0-realtime-plus</h2><button class=\"icon-btn\" type=\"button\" data-close-sheet aria-label=\"ปิด\">×</button></div><div class=\"idline\"><span>Alibaba /</span><code>qwen-audio-3.0-realtime-plus</code><button type=\"button\" id=\"copy-id\">คัดลอก ID</button></div><nav class=\"card-jump-nav\" aria-label=\"ส่วนต่าง ๆ ของการ์ดโมเดล\"><button type=\"button\" data-card-jump=\"overview\">เริ่มต้น</button><button type=\"button\" data-card-jump=\"methods\">อินพุตและเมธอด</button><button type=\"button\" data-card-jump=\"pricing\">ราคา</button><button type=\"button\" data-card-jump=\"examples\">ตัวอย่าง</button><button type=\"button\" data-card-jump=\"results\">ผลลัพธ์</button><button type=\"button\" data-card-jump=\"aliases\">ชื่ออื่น</button></nav><div class=\"card-method-tabs\" role=\"tablist\" aria-label=\"เมธอด API\"><button type=\"button\" role=\"tab\" tabindex=\"0\" aria-controls=\"card-method-content\" aria-selected=\"true\" id=\"card-method-tab-0\" data-card-method=\"Core|realtime|/v1/realtime?model=qwen-audio-3.0-realtime-plus|qwen-audio-3.0-realtime-plus\">เรียลไทม์</button></div><div id=\"card-method-content\" role=\"tabpanel\" aria-labelledby=\"card-method-tab-0\"><section class=\"card-section\" data-card-section=\"overview\"><h3 tabindex=\"-1\">เริ่มต้น</h3><p class=\"mdesc-full\">โมเดลสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ แล้วตอบด้วยเสียงหรือข้อความ ออกแบบสำหรับจังหวะการสนทนาที่เป็นธรรมชาติและการทำงานร่วมกับเครื่องมือ</p><dl class=\"card-io\" data-card-io><div><dt>อินพุตที่รองรับ</dt><dd>ข้อความ · เสียง</dd></div><div><dt>ผลลัพธ์</dt><dd>ข้อความ · เสียง</dd></div></dl><details class=\"card-about\"><summary>เกี่ยวกับโมเดล</summary><p class=\"note-s\" data-model-method-boundary>คำอธิบายนี้ครอบคลุมความสามารถของโมเดล อินพุต เอาต์พุต และตัวเลือกที่ใช้ได้ใน Ailoot แสดงด้านล่างตามเมธอดที่เลือก</p><div class=\"mabout\" id=\"m-about\"><p>Qwen-Audio-3.0-Realtime-Plus เป็นโมเดลของ Alibaba สำหรับสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ ตอบด้วยเสียงและข้อความ และรองรับการสนทนาโต้ตอบด้วยจังหวะรับส่งคำพูดที่เป็นธรรมชาติ สามารถส่งและรับเสียงเป็นส่วน ๆ ได้ การโต้ตอบจึงดำเนินต่อไปได้ระหว่างการสนทนา</p><h4>เมื่อคู่สนทนาพูดจบความคิด</h4><p>มีหลายวิธีในการตรวจจับจุดสิ้นสุดของการพูดแต่ละครั้ง ได้แก่ ตรวจจากกิจกรรมเสียง ตรวจจากความสมบูรณ์ของความหมาย และควบคุมอย่างชัดเจน ในระบบของผู้ผลิตต้องเลือกโหมดก่อนส่งเสียงครั้งแรก หากต้องการเปลี่ยนหลังเริ่มสนทนาแล้ว ต้องสร้างการเชื่อมต่อใหม่ การรองรับการควบคุมนี้ขึ้นอยู่กับวิธีที่เลือกใช้ โหมดตรวจความหมายคำนึงถึงการหยุดเว้นช่วงและคำที่ใช้คั่นระหว่างคิด การลังเลสั้น ๆ จึงไม่จำเป็นต้องหมายความว่าผู้ใช้พูดจบความคิดแล้ว เสียงพูดใหม่ของผู้ใช้สามารถขัดจังหวะคำตอบที่กำลังสร้าง เพื่อให้การสนทนาดำเนินต่อโดยคำนึงถึงคำพูดถัดไป ในโหมดตรวจความหมายสามารถใช้ตัวอย่างเสียงของคู่สนทนาที่เลือกเป็นแนวทางในการรู้จำ เพื่อลดการรบกวนจากเสียงผู้อื่นและเสียงพื้นหลัง</p><p>คำสั่งกำหนดบทบาทของผู้ช่วยและสไตล์การสื่อสาร การถ่ายทอดด้วยเสียงสามารถปรับตามน้ำเสียง จังหวะ และอารมณ์ เวอร์ชัน 3.0 มีเสียงระบบห้าเสียงและเสียงที่สร้างจากตัวอย่างเสียงพูด โมเดลรองรับ 11 ภาษา รวมถึงภาษารัสเซีย ตลอดจนรูปแบบภาษาถิ่นจีนที่ผู้ผลิตระบุ ในระบบของผู้ผลิตต้องกำหนดเสียงเมื่ออัปเดตการตั้งค่าเซสชันครั้งแรก การส่งเสียงใหม่ภายหลังในการสนทนาเดียวกันจะถูกละเลย การตั้งค่าเหล่านี้ต้องได้รับการรองรับจากวิธีเรียกใช้ที่เลือก</p><h4>เครื่องมือและประวัติการสนทนา</h4><p>รองรับการเรียกฟังก์ชัน โมเดลระบุการกระทำที่ต้องการ จากนั้นแอปพลิเคชันที่เชื่อมต่อจะดำเนินการและส่งผลกลับเข้าบทสนทนา ทำให้สามารถสนทนาโดยอ้างอิงข้อมูลจริง และดำเนินต่อหลังทำรายการแล้ว ผู้ช่วยเสียงสามารถใช้ผลจากเครื่องมือเป็นข้อมูลอ้างอิงพร้อมรักษาบริบทของการสนทนา ความสามารถของผู้ผลิตยังรวมถึงการค้นหาเว็บในตัว หากวิธีที่เลือกใช้รองรับ แต่ไม่สามารถเปิดการค้นหาเว็บและการเรียกฟังก์ชันพร้อมกันในเซสชันเดียวได้</p><p>ประวัติการสนทนามี 20 รอบโดยค่าเริ่มต้น และกำหนดได้ตั้งแต่หนึ่งถึง 50 รอบ เสียงที่สะสมไว้มีขีดจำกัด 300 วินาที เมื่อเกินขีดจำกัด ระบบจะลบส่วนเก่าของประวัติออก ข้อจำกัดนี้ต่างจากระยะเวลาของคำพูดแต่ละครั้ง เพราะประวัติเป็นตัวกำหนดว่าข้อมูลก่อนหน้านี้ส่วนใดยังใช้ได้เมื่อสนทนาต่อ</p><h4>บริบทข้อความและเสียง</h4><p>ขนาดบริบทตามข้อกำหนดคือ 40 960 โทเคน ความยาวอินพุตสูงสุดคือ 16 384 โทเคน และเอาต์พุตสูงสุด 8192 โทเคน โหมดใช้เหตุผลระบุขีดจำกัดอินพุตและเอาต์พุตเท่ากัน โดยมีขีดจำกัดสายการให้เหตุผลแยกต่างหากที่ 1024 โทเคน</p><p>เสียงแบบสตรีมใช้ PCM หนึ่งช่องสัญญาณแบบ 16 บิต โดยอินพุตมีอัตรา 16 kHz และเอาต์พุต 24 kHz ข้อความและข้อมูลเสียงอยู่ในบทสนทนาเดียวกัน สำหรับโมเดลนี้โดยเฉพาะ ยังไม่มีการระบุอินพุตภาพหรือเอาต์พุตภาพ ความเชี่ยวชาญของโมเดลคือเสียงพูด ข้อความ และการโต้ตอบด้วยเสียง</p></div></details></section><section class=\"card-section\" data-card-section=\"methods\"><h3 tabindex=\"-1\">ใช้งานได้ใน Ailoot · อินพุตและเมธอด</h3><details class=\"card-method\" open><summary><b>Ailoot · เสียงแบบเรียลไทม์</b> <code>GET /v1/realtime?model=qwen-audio-3.0-realtime-plus</code></summary><dl class=\"method-capabilities\"><div><dt>ขาเข้า</dt><dd><code>text</code>, <code>audio</code></dd></div><div><dt>ขาออก</dt><dd><code>text</code>, <code>audio</code></dd></div><div><dt>รูปแบบเอาต์พุต</dt><dd>เหตุการณ์ของเซสชัน</dd></div></dl><div class=\"tw\" data-card-parameters data-typed-parameters><table><thead><tr><th>ฟิลด์</th><th>ประเภท</th><th>ข้อกำหนด</th><th>ค่าและข้อจำกัด</th><th>ค่าเริ่มต้น</th></tr></thead><tbody><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">query.model</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>string</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>จำเป็น</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>qwen-audio-3.0-realtime-plus</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">session.input_audio_format</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>string</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>ไม่บังคับ</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>pcm16, pcm</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">session.output_audio_format</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>string</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>ไม่บังคับ</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>pcm16, pcm</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">session.instructions</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>string</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>ไม่บังคับ</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>ข้อจำกัดใช้กับ: นโยบายเซสชันที่เลือก</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">session.max_history_turns</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>integer</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>ไม่บังคับ</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>ขั้นต่ำ: 1</div><div>ข้อจำกัดใช้กับ: นโยบายเซสชันที่เลือก</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr><tr data-parameter-availability=\"source_interface\"><th data-cell-label=\"ฟิลด์\" scope=\"row\"><span class=\"card-cell-label\">ฟิลด์</span><code class=\"card-field-name\">input_audio_buffer.append.audio</code></th><td data-cell-label=\"ประเภท\" data-field-type><span class=\"card-cell-label\">ประเภท</span><code>base64_string</code></td><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>จำเป็น</td><td data-cell-label=\"ค่าและข้อจำกัด\"><span class=\"card-cell-label\">ค่าและข้อจำกัด</span><div>เนื้อหาอินพุต: PCM16 แบบโมโน ขาเข้า 16 kHz ขาออก 24 kHz ความยาวไบต์ต้องไม่เป็นศูนย์และเป็นจำนวนคู่</div></td><td data-cell-label=\"ค่าเริ่มต้น\" data-default=\"unspecified\"><span class=\"card-cell-label\">ค่าเริ่มต้น</span>—</td></tr></tbody></table></div><details class=\"card-about\" data-material-combinations><summary>ชุดผสมของสื่ออินพุต</summary><p class=\"note-s\"><b>realtime_text_audio</b></p></details><details class=\"note-s\" data-method-contract><summary>พารามิเตอร์และวงจรการทำงานของเมธอด</summary><div class=\"tw\" data-card-table=\"contract\"><table><thead><tr><th>พารามิเตอร์</th><th>ข้อกำหนด</th></tr></thead><tbody><tr><th data-cell-label=\"พารามิเตอร์\" scope=\"row\"><span class=\"card-cell-label\">พารามิเตอร์</span><code>material_types</code></th><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>text, audio</td></tr><tr><th data-cell-label=\"พารามิเตอร์\" scope=\"row\"><span class=\"card-cell-label\">พารามิเตอร์</span><code>required</code></th><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>null</td></tr><tr><th data-cell-label=\"พารามิเตอร์\" scope=\"row\"><span class=\"card-cell-label\">พารามิเตอร์</span><code>optional_controls</code></th><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>null</td></tr><tr><th data-cell-label=\"พารามิเตอร์\" scope=\"row\"><span class=\"card-cell-label\">พารามิเตอร์</span><code>content_type</code></th><td data-cell-label=\"ข้อกำหนด\"><span class=\"card-cell-label\">ข้อกำหนด</span>WebSocket</td></tr></tbody></table></div><p>วงจรการทำงาน: <code>exact retained published method</code></p><p class=\"note-s\">รูปแบบเมธอดและ ID ระบุอย่างแม่นยำ ความสามารถของผู้ให้บริการแยกจากการอนุญาตให้รับคำขอ</p></details></details></section><section class=\"card-section\" data-card-section=\"pricing\"><h3 tabindex=\"-1\">ราคา</h3><h4>อัตราค่าบริการเมธอด Ailoot</h4><section class=\"meth\" data-route=\"Core\"><header><b><span class=\"alias\">Ailoot</span> เสียงแบบเรียลไทม์</b><code>GET /v1/realtime?model=qwen-audio-3.0-realtime-plus</code></header><dl><div><dt>ขาเข้า</dt><dd>US$0.0008 <em>/ 1K</em></dd></div><div><dt>ขาออก</dt><dd>US$0.0064 <em>/ 1K</em></dd></div><div><dt>ขาเข้า</dt><dd>US$0.0048 <em>ต่อนาทีของเสียง</em></dd></div><div><dt>ขาออก</dt><dd>US$0.018 <em>ต่อนาทีของเสียงเอาต์พุต</em></dd></div></dl></section><p class=\"note-s\">Ailoot กันยอดเงินประมาณการไว้ก่อนส่งคำขอ หลังได้ผลลัพธ์ จะคิดค่าบริการสุดท้ายตามการใช้งานที่วัดได้ การคิดค่าบริการแบบสตรีมใช้บันทึกการใช้งานสุดท้าย <a href=\"/docs/th/billing/reserve/\">วิธีกันยอดเงินและคิดค่าบริการสุดท้าย →</a></p></section><section class=\"card-section\" data-card-section=\"examples\"><h3 tabindex=\"-1\">ตัวอย่างคำขอ</h3><h4>Ailoot · เสียงแบบเรียลไทม์</h4><div class=\"code-group\"><div class=\"cg-bar\"><div class=\"cg-tabs\" role=\"tablist\" aria-label=\"ตัวเลือกโค้ด\"><button class=\"cg-tab\" id=\"model-code-40-tab-0\" role=\"tab\" type=\"button\" aria-controls=\"model-code-40-panel-0\" aria-selected=\"true\" tabindex=\"0\">Python WebSocket · ข้อความ</button><button class=\"cg-tab\" id=\"model-code-40-tab-1\" role=\"tab\" type=\"button\" aria-controls=\"model-code-40-panel-1\" aria-selected=\"false\" tabindex=\"-1\">Python WebSocket · เสียง</button></div><div class=\"cg-tools\"><button class=\"cg-btn cg-copy\" type=\"button\" aria-label=\"คัดลอกโค้ด\"><svg class=\"cp\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\"><rect x=\"5.25\" y=\"5.25\" width=\"8.5\" height=\"8.5\" rx=\"1.75\"/><path d=\"M10.75 5.25V3.5a1.25 1.25 0 0 0-1.25-1.25H3.5A1.25 1.25 0 0 0 2.25 3.5v6a1.25 1.25 0 0 0 1.25 1.25h1.75\"/></svg><svg class=\"ok\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\"><path d=\"m3 8.5 3.25 3.25L13 5\"/></svg></button></div></div><div class=\"cg-body\"><div class=\"cg-pane\" id=\"model-code-40-panel-0\" role=\"tabpanel\" aria-labelledby=\"model-code-40-tab-0\"><pre data-lang=\"python\"><code># Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(&quot;AILOOT_API_KEY&quot;, &quot;&quot;)\nif not key.strip():\n    raise SystemExit(&quot;Set your AILOOT_API_KEY before connecting&quot;)\nfile = Path(os.environ.get(&quot;AILOOT_TEXT_FILE&quot;, &quot;&quot;))\nif not file.is_file(): raise SystemExit(&quot;Set AILOOT_TEXT_FILE to your actual UTF-8 material&quot;)\nmaterial = file.read_text(encoding=&quot;utf-8&quot;)\nif not material.strip(): raise SystemExit(&quot;Text material must not be empty&quot;)\nout = Path(&quot;realtime-results&quot;)\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left &lt;= 0:\n        raise TimeoutError(&quot;Client session limit; preserve IDs and partial results, do not replay&quot;)\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + &quot;\\n&quot;)\n    log.flush()\n    kind = event.get(&quot;type&quot;)\n    if kind == &quot;error&quot;:\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == &quot;response.created&quot;:\n        current_response = event[&quot;response&quot;][&quot;id&quot;]\n    if kind in {&quot;response.audio.delta&quot;, &quot;response.output_audio.delta&quot;, &quot;response.text.delta&quot;, &quot;response.output_text.delta&quot;, &quot;response.audio_transcript.delta&quot;, &quot;response.output_audio_transcript.delta&quot;, &quot;response.text.done&quot;, &quot;response.audio_transcript.done&quot;}:\n        identity = (event[&quot;response_id&quot;], event[&quot;item_id&quot;], event[&quot;output_index&quot;], event[&quot;content_index&quot;])\n        if kind in {&quot;response.audio.delta&quot;, &quot;response.output_audio.delta&quot;}:\n            raw = base64.b64decode(event[&quot;delta&quot;], validate=True)\n            if len(raw) % 2: raise ValueError(&quot;Output PCM16 chunk must have an even byte length&quot;)\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(&quot;.done&quot;):\n            texts[identity] = event.get(&quot;text&quot;, event.get(&quot;transcript&quot;, &quot;&quot;))\n        else:\n            texts[identity] = texts.get(identity, &quot;&quot;) + event[&quot;delta&quot;]\n            print(event[&quot;delta&quot;], end=&quot;&quot;, flush=True)\n    if kind == &quot;response.done&quot;:\n        response = event[&quot;response&quot;]\n        complete.append(response)\n        if current_response is None: current_response = response[&quot;id&quot;]\n        if response[&quot;id&quot;] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(&quot;type&quot;) == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(&quot;wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus&quot;, additional_headers={&quot;Authorization&quot;: &quot;Bearer &quot; + key}) as ws:\n        with (out / &quot;events.jsonl&quot;).open(&quot;w&quot;, encoding=&quot;utf-8&quot;) as log:\n            wait_for(ws, log, &quot;session.created&quot;)\n            send(ws, {&quot;type&quot;:&quot;session.update&quot;, &quot;session&quot;:{&quot;modalities&quot;:[&quot;audio&quot;,&quot;text&quot;], &quot;input_audio_format&quot;:&quot;pcm&quot;, &quot;output_audio_format&quot;:&quot;pcm&quot;, &quot;turn_detection&quot;:None}})\n            wait_for(ws, log, &quot;session.updated&quot;)\n            send(ws, {&quot;type&quot;:&quot;conversation.item.create&quot;, &quot;item&quot;:{&quot;type&quot;:&quot;message&quot;, &quot;role&quot;:&quot;user&quot;, &quot;content&quot;:[{&quot;type&quot;:&quot;input_text&quot;, &quot;text&quot;:material}]}})\n            send(ws, {&quot;type&quot;:&quot;response.create&quot;})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {&quot;type&quot;:&quot;response.cancel&quot;})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(&quot;status&quot;) != &quot;completed&quot;:\n        raise RuntimeError(&quot;Response did not complete normally; inspect saved events and status&quot;)\nfinally:\n    manifest = {&quot;responses&quot;:complete, &quot;parts&quot;:[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {&quot;response_id&quot;:identity[0], &quot;item_id&quot;:identity[1], &quot;output_index&quot;:identity[2], &quot;content_index&quot;:identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (&quot;audio-&quot; + str(number) + &quot;.pcm&quot;)\n            wav_file = out / (&quot;audio-&quot; + str(number) + &quot;.wav&quot;)\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), &quot;wb&quot;) as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({&quot;pcm&quot;:str(pcm_file), &quot;wav&quot;:str(wav_file), &quot;sample_rate_hz&quot;:24000})\n        if identity in texts:\n            text_file = out / (&quot;text-&quot; + str(number) + &quot;.txt&quot;)\n            text_file.write_text(texts[identity], encoding=&quot;utf-8&quot;)\n            record[&quot;text&quot;] = str(text_file)\n        manifest[&quot;parts&quot;].append(record)\n    (out / &quot;results.json&quot;).write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=&quot;utf-8&quot;)\n    print(&quot;\\nSaved every received event and result in&quot;, out)\n</code></pre></div><div class=\"cg-pane\" id=\"model-code-40-panel-1\" role=\"tabpanel\" aria-labelledby=\"model-code-40-tab-1\" hidden><pre data-lang=\"python\"><code># Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(&quot;AILOOT_API_KEY&quot;, &quot;&quot;)\nif not key.strip():\n    raise SystemExit(&quot;Set your AILOOT_API_KEY before connecting&quot;)\nfile = Path(os.environ.get(&quot;AILOOT_AUDIO_FILE&quot;, &quot;&quot;))\nif not file.is_file(): raise SystemExit(&quot;Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording&quot;)\nmaterial = file.read_bytes()\nif not material or len(material) % 2 or material.startswith(b&quot;RIFF&quot;):\n    raise SystemExit(&quot;Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header&quot;)\nout = Path(&quot;realtime-results&quot;)\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left &lt;= 0:\n        raise TimeoutError(&quot;Client session limit; preserve IDs and partial results, do not replay&quot;)\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + &quot;\\n&quot;)\n    log.flush()\n    kind = event.get(&quot;type&quot;)\n    if kind == &quot;error&quot;:\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == &quot;response.created&quot;:\n        current_response = event[&quot;response&quot;][&quot;id&quot;]\n    if kind in {&quot;response.audio.delta&quot;, &quot;response.output_audio.delta&quot;, &quot;response.text.delta&quot;, &quot;response.output_text.delta&quot;, &quot;response.audio_transcript.delta&quot;, &quot;response.output_audio_transcript.delta&quot;, &quot;response.text.done&quot;, &quot;response.audio_transcript.done&quot;}:\n        identity = (event[&quot;response_id&quot;], event[&quot;item_id&quot;], event[&quot;output_index&quot;], event[&quot;content_index&quot;])\n        if kind in {&quot;response.audio.delta&quot;, &quot;response.output_audio.delta&quot;}:\n            raw = base64.b64decode(event[&quot;delta&quot;], validate=True)\n            if len(raw) % 2: raise ValueError(&quot;Output PCM16 chunk must have an even byte length&quot;)\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(&quot;.done&quot;):\n            texts[identity] = event.get(&quot;text&quot;, event.get(&quot;transcript&quot;, &quot;&quot;))\n        else:\n            texts[identity] = texts.get(identity, &quot;&quot;) + event[&quot;delta&quot;]\n            print(event[&quot;delta&quot;], end=&quot;&quot;, flush=True)\n    if kind == &quot;response.done&quot;:\n        response = event[&quot;response&quot;]\n        complete.append(response)\n        if current_response is None: current_response = response[&quot;id&quot;]\n        if response[&quot;id&quot;] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(&quot;type&quot;) == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(&quot;wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus&quot;, additional_headers={&quot;Authorization&quot;: &quot;Bearer &quot; + key}) as ws:\n        with (out / &quot;events.jsonl&quot;).open(&quot;w&quot;, encoding=&quot;utf-8&quot;) as log:\n            wait_for(ws, log, &quot;session.created&quot;)\n            send(ws, {&quot;type&quot;:&quot;session.update&quot;, &quot;session&quot;:{&quot;modalities&quot;:[&quot;audio&quot;,&quot;text&quot;], &quot;input_audio_format&quot;:&quot;pcm&quot;, &quot;output_audio_format&quot;:&quot;pcm&quot;, &quot;turn_detection&quot;:None}})\n            wait_for(ws, log, &quot;session.updated&quot;)\n            for offset in range(0, len(material), 640):\n                send(ws, {&quot;type&quot;:&quot;input_audio_buffer.append&quot;, &quot;audio&quot;:base64.b64encode(material[offset:offset+640]).decode(&quot;ascii&quot;)})\n                time.sleep(0.02)\n            send(ws, {&quot;type&quot;:&quot;input_audio_buffer.commit&quot;})\n            wait_for(ws, log, &quot;input_audio_buffer.committed&quot;)\n            send(ws, {&quot;type&quot;:&quot;response.create&quot;})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {&quot;type&quot;:&quot;response.cancel&quot;})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(&quot;status&quot;) != &quot;completed&quot;:\n        raise RuntimeError(&quot;Response did not complete normally; inspect saved events and status&quot;)\nfinally:\n    manifest = {&quot;responses&quot;:complete, &quot;parts&quot;:[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {&quot;response_id&quot;:identity[0], &quot;item_id&quot;:identity[1], &quot;output_index&quot;:identity[2], &quot;content_index&quot;:identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (&quot;audio-&quot; + str(number) + &quot;.pcm&quot;)\n            wav_file = out / (&quot;audio-&quot; + str(number) + &quot;.wav&quot;)\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), &quot;wb&quot;) as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({&quot;pcm&quot;:str(pcm_file), &quot;wav&quot;:str(wav_file), &quot;sample_rate_hz&quot;:24000})\n        if identity in texts:\n            text_file = out / (&quot;text-&quot; + str(number) + &quot;.txt&quot;)\n            text_file.write_text(texts[identity], encoding=&quot;utf-8&quot;)\n            record[&quot;text&quot;] = str(text_file)\n        manifest[&quot;parts&quot;].append(record)\n    (out / &quot;results.json&quot;).write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=&quot;utf-8&quot;)\n    print(&quot;\\nSaved every received event and result in&quot;, out)\n</code></pre></div></div></div></section><section class=\"card-section\" data-card-section=\"results\"><h3 tabindex=\"-1\">รับและบันทึกผลลัพธ์</h3><h4>Ailoot · เสียงแบบเรียลไทม์</h4><p class=\"note-s\">เหตุการณ์ของเซสชัน</p><div class=\"card-result-process\" data-all-results><h5>เก็บผลลัพธ์ที่เสร็จสมบูรณ์ทั้งหมด</h5><p class=\"note-s\">เก็บทุกการตอบกลับ ไฟล์ และส่วนเนื้อหาที่ส่งกลับมาอย่างครบถ้วน</p><p class=\"note-s\">ประกอบข้อมูลเสียงส่วนเพิ่มและผลลัพธ์ข้อความ/เหตุการณ์ทั้งหมดที่ส่งกลับสำหรับ ID การตอบกลับจริงแต่ละรายการ</p></div><div class=\"card-result-process\" data-unknown-recovery><h5>เมื่อต้องตรวจสอบการตอบกลับต้นฉบับ</h5><p class=\"note-s\">เก็บ ID เซสชัน/การตอบกลับ/เหตุการณ์จริงและหลักฐานบันทึก</p></div><details class=\"card-about\" data-method-errors><summary>ข้อผิดพลาดและขั้นตอนถัดไป</summary><div class=\"tw\" data-card-table=\"errors\"><table><thead><tr><th>การตอบกลับ</th><th>เงื่อนไข</th><th>ขั้นตอนถัดไป</th></tr></thead><tbody><tr><th data-cell-label=\"การตอบกลับ\" scope=\"row\"><span class=\"card-cell-label\">การตอบกลับ</span>426 · <code>invalid_request_error</code></th><td data-cell-label=\"เงื่อนไข\"><span class=\"card-cell-label\">เงื่อนไข</span>ไม่มีการอัปเกรด WebSocket</td><td data-cell-label=\"ขั้นตอนถัดไป\"><span class=\"card-cell-label\">ขั้นตอนถัดไป</span>ใช้ไคลเอนต์ WebSocket พร้อม Upgrade: websocket</td></tr></tbody></table></div></details></section><section class=\"card-section\" data-card-section=\"aliases\"><h3 tabindex=\"-1\">ชื่ออื่น</h3><h4>ชื่ออื่นของโมเดล</h4><p class=\"note-s\"><span data-model-alias-route=\"Core\"><b>Ailoot</b> <a href=\"#m=qwen-audio-3.0-realtime-plus&amp;route=Core&amp;caller=qwen-audio-3.0-realtime-plus&amp;fmt=realtime\"><code>qwen-audio-3.0-realtime-plus</code></a></span></p><h4>ชื่อพาธเมธอดอื่น</h4><p class=\"note-s\">ใช้พาธเมธอดที่แสดงด้านบน</p><h4>ID ที่เกี่ยวข้องสำหรับเรียกใช้โมเดล</h4><p class=\"note-s\"><a href=\"#m=qwen-audio-3.0-realtime-plus&amp;route=Core&amp;caller=qwen-audio-3.0-realtime-plus&amp;fmt=realtime\"><code>qwen-audio-3.0-realtime-plus</code></a></p></section></div>",
      "method_identity": {
        "effective_request_model_id": "qwen-audio-3.0-realtime-plus",
        "fmt": "realtime",
        "http": "GET",
        "path": "/v1/realtime?model=qwen-audio-3.0-realtime-plus",
        "request_model_id": "qwen-audio-3.0-realtime-plus",
        "route_label": "Core"
      },
      "method_key": "Core|realtime|/v1/realtime?model=qwen-audio-3.0-realtime-plus|qwen-audio-3.0-realtime-plus",
      "ordinal": 0,
      "rawMethod": {
        "cache_read": null,
        "cache_write": null,
        "cache_write_1h": null,
        "cache_write_5m": null,
        "conditional_meter": null,
        "contract": {
          "data": {
            "all_results": "ประกอบข้อมูลเสียงส่วนเพิ่มและผลลัพธ์ข้อความ/เหตุการณ์ทั้งหมดที่ส่งกลับสำหรับ ID การตอบกลับจริงแต่ละรายการ",
            "endpoint": {
              "http": "GET",
              "path": "/v1/realtime",
              "query": {
                "model": "qwen-audio-3.0-realtime-plus"
              },
              "transport": "WebSocket",
              "url": "wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus"
            },
            "errors": [
              {
                "condition": "ไม่มีการอัปเกรด WebSocket",
                "http_status": 426,
                "recovery": "ใช้ไคลเอนต์ WebSocket พร้อม Upgrade: websocket",
                "type": "invalid_request_error"
              }
            ],
            "hints": [
              "Append the model query once; do not add another ?model to a URL that already contains it.",
              "Use the actual WebSocket upgrade and API-key authentication.",
              "Tools, web search and voiceprint enhancement are not supported on this exact route."
            ],
            "ignored_fields": [],
            "lifecycle": {
              "close": "Close the actual establishedWebSocket session; no fakeHTTP cancelpath.",
              "mode": "WebSocket session",
              "unknown": "เก็บ ID เซสชัน/การตอบกลับ/เหตุการณ์จริงและหลักฐานบันทึก"
            },
            "material_combinations": [
              {
                "events": [
                  "session.update",
                  "input_audio_buffer.append",
                  "input_audio_buffer.commit",
                  "input_audio_buffer.clear",
                  "response.create",
                  "response.cancel",
                  "conversation.item.create",
                  "conversation.item.retrieve",
                  "conversation.item.delete"
                ],
                "mode": "realtime_text_audio"
              }
            ],
            "operation_modes": [
              "realtime_text_audio"
            ],
            "outputs": {
              "all_outputs": "Assemble every returned audio delta and text/event result for each actual response ID.",
              "audio_format": "PCM16 mono 24 kHz",
              "family": [
                "text",
                "audio"
              ],
              "format": "เหตุการณ์ของเซสชัน"
            },
            "parameters": [
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "qwen-audio-3.0-realtime-plus"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "query.model",
                "required": true,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "pcm16",
                  "pcm"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "session.input_audio_format",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "pcm16",
                  "pcm"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "session.output_audio_format",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "limit_scope": "นโยบายเซสชันที่เลือก",
                "name": "session.instructions",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "limit_scope": "นโยบายเซสชันที่เลือก",
                "minimum": 1,
                "name": "session.max_history_turns",
                "required": false,
                "type": "integer"
              },
              {
                "availability": "source_interface",
                "content": "PCM16 แบบโมโน ขาเข้า 16 kHz ขาออก 24 kHz ความยาวไบต์ต้องไม่เป็นศูนย์และเป็นจำนวนคู่",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "name": "input_audio_buffer.append.audio",
                "required": true,
                "type": "base64_string"
              }
            ],
            "unsupported": []
          },
          "hints": [
            "รูปแบบเมธอดและ ID ระบุอย่างแม่นยำ ความสามารถของผู้ให้บริการแยกจากการอนุญาตให้รับคำขอ"
          ],
          "input": {
            "content_type": "WebSocket",
            "material_types": [
              "text",
              "audio"
            ],
            "optional_controls": null,
            "required": null
          },
          "lifecycle": {
            "mode": "exact retained published method"
          },
          "method": {
            "http": "GET",
            "path": "/v1/realtime?model=qwen-audio-3.0-realtime-plus"
          },
          "operation_modes": [
            "realtime"
          ],
          "output": {
            "family": [
              "text",
              "audio"
            ],
            "format": "session events",
            "multioutputs": "retain every actual response output"
          }
        },
        "ctx": null,
        "examples": [
          {
            "code": "# Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(\"AILOOT_API_KEY\", \"\")\nif not key.strip():\n    raise SystemExit(\"Set your AILOOT_API_KEY before connecting\")\nfile = Path(os.environ.get(\"AILOOT_TEXT_FILE\", \"\"))\nif not file.is_file(): raise SystemExit(\"Set AILOOT_TEXT_FILE to your actual UTF-8 material\")\nmaterial = file.read_text(encoding=\"utf-8\")\nif not material.strip(): raise SystemExit(\"Text material must not be empty\")\nout = Path(\"realtime-results\")\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left <= 0:\n        raise TimeoutError(\"Client session limit; preserve IDs and partial results, do not replay\")\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n    log.flush()\n    kind = event.get(\"type\")\n    if kind == \"error\":\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == \"response.created\":\n        current_response = event[\"response\"][\"id\"]\n    if kind in {\"response.audio.delta\", \"response.output_audio.delta\", \"response.text.delta\", \"response.output_text.delta\", \"response.audio_transcript.delta\", \"response.output_audio_transcript.delta\", \"response.text.done\", \"response.audio_transcript.done\"}:\n        identity = (event[\"response_id\"], event[\"item_id\"], event[\"output_index\"], event[\"content_index\"])\n        if kind in {\"response.audio.delta\", \"response.output_audio.delta\"}:\n            raw = base64.b64decode(event[\"delta\"], validate=True)\n            if len(raw) % 2: raise ValueError(\"Output PCM16 chunk must have an even byte length\")\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(\".done\"):\n            texts[identity] = event.get(\"text\", event.get(\"transcript\", \"\"))\n        else:\n            texts[identity] = texts.get(identity, \"\") + event[\"delta\"]\n            print(event[\"delta\"], end=\"\", flush=True)\n    if kind == \"response.done\":\n        response = event[\"response\"]\n        complete.append(response)\n        if current_response is None: current_response = response[\"id\"]\n        if response[\"id\"] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(\"type\") == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(\"wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus\", additional_headers={\"Authorization\": \"Bearer \" + key}) as ws:\n        with (out / \"events.jsonl\").open(\"w\", encoding=\"utf-8\") as log:\n            wait_for(ws, log, \"session.created\")\n            send(ws, {\"type\":\"session.update\", \"session\":{\"modalities\":[\"audio\",\"text\"], \"input_audio_format\":\"pcm\", \"output_audio_format\":\"pcm\", \"turn_detection\":None}})\n            wait_for(ws, log, \"session.updated\")\n            send(ws, {\"type\":\"conversation.item.create\", \"item\":{\"type\":\"message\", \"role\":\"user\", \"content\":[{\"type\":\"input_text\", \"text\":material}]}})\n            send(ws, {\"type\":\"response.create\"})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {\"type\":\"response.cancel\"})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(\"status\") != \"completed\":\n        raise RuntimeError(\"Response did not complete normally; inspect saved events and status\")\nfinally:\n    manifest = {\"responses\":complete, \"parts\":[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {\"response_id\":identity[0], \"item_id\":identity[1], \"output_index\":identity[2], \"content_index\":identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (\"audio-\" + str(number) + \".pcm\")\n            wav_file = out / (\"audio-\" + str(number) + \".wav\")\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), \"wb\") as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({\"pcm\":str(pcm_file), \"wav\":str(wav_file), \"sample_rate_hz\":24000})\n        if identity in texts:\n            text_file = out / (\"text-\" + str(number) + \".txt\")\n            text_file.write_text(texts[identity], encoding=\"utf-8\")\n            record[\"text\"] = str(text_file)\n        manifest[\"parts\"].append(record)\n    (out / \"results.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    print(\"\\nSaved every received event and result in\", out)\n",
            "label": "Python WebSocket · text material and all text/audio results",
            "language": "python"
          },
          {
            "code": "# Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(\"AILOOT_API_KEY\", \"\")\nif not key.strip():\n    raise SystemExit(\"Set your AILOOT_API_KEY before connecting\")\nfile = Path(os.environ.get(\"AILOOT_AUDIO_FILE\", \"\"))\nif not file.is_file(): raise SystemExit(\"Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording\")\nmaterial = file.read_bytes()\nif not material or len(material) % 2 or material.startswith(b\"RIFF\"):\n    raise SystemExit(\"Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header\")\nout = Path(\"realtime-results\")\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left <= 0:\n        raise TimeoutError(\"Client session limit; preserve IDs and partial results, do not replay\")\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n    log.flush()\n    kind = event.get(\"type\")\n    if kind == \"error\":\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == \"response.created\":\n        current_response = event[\"response\"][\"id\"]\n    if kind in {\"response.audio.delta\", \"response.output_audio.delta\", \"response.text.delta\", \"response.output_text.delta\", \"response.audio_transcript.delta\", \"response.output_audio_transcript.delta\", \"response.text.done\", \"response.audio_transcript.done\"}:\n        identity = (event[\"response_id\"], event[\"item_id\"], event[\"output_index\"], event[\"content_index\"])\n        if kind in {\"response.audio.delta\", \"response.output_audio.delta\"}:\n            raw = base64.b64decode(event[\"delta\"], validate=True)\n            if len(raw) % 2: raise ValueError(\"Output PCM16 chunk must have an even byte length\")\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(\".done\"):\n            texts[identity] = event.get(\"text\", event.get(\"transcript\", \"\"))\n        else:\n            texts[identity] = texts.get(identity, \"\") + event[\"delta\"]\n            print(event[\"delta\"], end=\"\", flush=True)\n    if kind == \"response.done\":\n        response = event[\"response\"]\n        complete.append(response)\n        if current_response is None: current_response = response[\"id\"]\n        if response[\"id\"] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(\"type\") == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(\"wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus\", additional_headers={\"Authorization\": \"Bearer \" + key}) as ws:\n        with (out / \"events.jsonl\").open(\"w\", encoding=\"utf-8\") as log:\n            wait_for(ws, log, \"session.created\")\n            send(ws, {\"type\":\"session.update\", \"session\":{\"modalities\":[\"audio\",\"text\"], \"input_audio_format\":\"pcm\", \"output_audio_format\":\"pcm\", \"turn_detection\":None}})\n            wait_for(ws, log, \"session.updated\")\n            for offset in range(0, len(material), 640):\n                send(ws, {\"type\":\"input_audio_buffer.append\", \"audio\":base64.b64encode(material[offset:offset+640]).decode(\"ascii\")})\n                time.sleep(0.02)\n            send(ws, {\"type\":\"input_audio_buffer.commit\"})\n            wait_for(ws, log, \"input_audio_buffer.committed\")\n            send(ws, {\"type\":\"response.create\"})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {\"type\":\"response.cancel\"})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(\"status\") != \"completed\":\n        raise RuntimeError(\"Response did not complete normally; inspect saved events and status\")\nfinally:\n    manifest = {\"responses\":complete, \"parts\":[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {\"response_id\":identity[0], \"item_id\":identity[1], \"output_index\":identity[2], \"content_index\":identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (\"audio-\" + str(number) + \".pcm\")\n            wav_file = out / (\"audio-\" + str(number) + \".wav\")\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), \"wb\") as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({\"pcm\":str(pcm_file), \"wav\":str(wav_file), \"sample_rate_hz\":24000})\n        if identity in texts:\n            text_file = out / (\"text-\" + str(number) + \".txt\")\n            text_file.write_text(texts[identity], encoding=\"utf-8\")\n            record[\"text\"] = str(text_file)\n        manifest[\"parts\"].append(record)\n    (out / \"results.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    print(\"\\nSaved every received event and result in\", out)\n",
            "label": "Python WebSocket · actual PCM recording and all results",
            "language": "python"
          }
        ],
        "family": "openai",
        "fast_multiplier": null,
        "flex_multiplier": null,
        "fmt": "realtime",
        "http": "GET",
        "img_in": null,
        "img_out": null,
        "in": 0.8,
        "input": [
          "text",
          "audio"
        ],
        "label": "เสียงแบบเรียลไทม์",
        "max_out": null,
        "max_tool_calls": null,
        "out": 6.4,
        "output": [
          "text",
          "audio"
        ],
        "path": "/v1/realtime?model=qwen-audio-3.0-realtime-plus",
        "pricing_profiles": [
          {
            "dimensions": {},
            "label": "Core",
            "units": [
              {
                "amount": 0.8,
                "amount_unit": "usd_per_million_tokens",
                "key": "in",
                "label": "Input",
                "side": "in"
              },
              {
                "amount": 6.4,
                "amount_unit": "usd_per_million_tokens",
                "key": "out",
                "label": "Output",
                "side": "out"
              },
              {
                "amount": 0.0048,
                "amount_unit": "usd_per_display_unit",
                "key": "audio_input_second",
                "label": "per minute of audio",
                "side": "in"
              },
              {
                "amount": 0.018,
                "amount_unit": "usd_per_display_unit",
                "key": "audio_output_second",
                "label": "per minute of output audio",
                "side": "out"
              }
            ]
          }
        ],
        "request_model_id": "qwen-audio-3.0-realtime-plus",
        "route_label": "Core",
        "status_reads": [],
        "tiers": [],
        "tool_prices": null,
        "unit": "conditional",
        "units": [
          {
            "key": "audio_input_second",
            "label": "per minute of audio",
            "side": "in",
            "usd": 0.0048
          },
          {
            "key": "audio_output_second",
            "label": "per minute of output audio",
            "side": "out",
            "usd": 0.018
          }
        ]
      }
    }
  ],
  "model_id": "qwen-audio-3.0-realtime-plus",
  "nativeProvenance": {
    "input_facts_canonical_sha256": "98b84cf271ff91ce059a21841c233604f7877841a48e48ae837047e2b69bcab9",
    "input_html_sha256": "8df99ce3d9292525c83366f73559808fd7ccdd94335a4d6aab9e8c0218cdbbcc",
    "private_audit_sha256": "c4ab33c630be925b9620a1d8c538eea66472885edf92a27db48fec7e2c76cccb",
    "role": "historical-normalized-input-audit-hashes",
    "schema": "ailoot-native-model-provenance-v2"
  },
  "page": {
    "canonical": "https://ailoot.ai/models/th/qwen-audio-3-0-realtime-plus/",
    "description": "โมเดลสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ แล้วตอบด้วยเสียงหรือข้อความ ออกแบบสำหรับจังหวะการสนทนาที่เป็นธรรมชาติและการทำงานร่วมกับเครื่องมือ",
    "locale": "th",
    "md_url": "https://ailoot.ai/models/th/qwen-audio-3-0-realtime-plus/index.md",
    "title": "qwen-audio-3.0-realtime-plus — Ailoot",
    "url": "https://ailoot.ai/models/th/qwen-audio-3-0-realtime-plus/"
  },
  "rawModel": {
    "about": "Qwen-Audio-3.0-Realtime-Plus เป็นโมเดลของ Alibaba สำหรับสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ ตอบด้วยเสียงและข้อความ และรองรับการสนทนาโต้ตอบด้วยจังหวะรับส่งคำพูดที่เป็นธรรมชาติ สามารถส่งและรับเสียงเป็นส่วน ๆ ได้ การโต้ตอบจึงดำเนินต่อไปได้ระหว่างการสนทนา\n\n### เมื่อคู่สนทนาพูดจบความคิด\n\nมีหลายวิธีในการตรวจจับจุดสิ้นสุดของการพูดแต่ละครั้ง ได้แก่ ตรวจจากกิจกรรมเสียง ตรวจจากความสมบูรณ์ของความหมาย และควบคุมอย่างชัดเจน ในระบบของผู้ผลิตต้องเลือกโหมดก่อนส่งเสียงครั้งแรก หากต้องการเปลี่ยนหลังเริ่มสนทนาแล้ว ต้องสร้างการเชื่อมต่อใหม่ การรองรับการควบคุมนี้ขึ้นอยู่กับวิธีที่เลือกใช้ โหมดตรวจความหมายคำนึงถึงการหยุดเว้นช่วงและคำที่ใช้คั่นระหว่างคิด การลังเลสั้น ๆ จึงไม่จำเป็นต้องหมายความว่าผู้ใช้พูดจบความคิดแล้ว เสียงพูดใหม่ของผู้ใช้สามารถขัดจังหวะคำตอบที่กำลังสร้าง เพื่อให้การสนทนาดำเนินต่อโดยคำนึงถึงคำพูดถัดไป ในโหมดตรวจความหมายสามารถใช้ตัวอย่างเสียงของคู่สนทนาที่เลือกเป็นแนวทางในการรู้จำ เพื่อลดการรบกวนจากเสียงผู้อื่นและเสียงพื้นหลัง\n\nคำสั่งกำหนดบทบาทของผู้ช่วยและสไตล์การสื่อสาร การถ่ายทอดด้วยเสียงสามารถปรับตามน้ำเสียง จังหวะ และอารมณ์ เวอร์ชัน 3.0 มีเสียงระบบห้าเสียงและเสียงที่สร้างจากตัวอย่างเสียงพูด โมเดลรองรับ 11 ภาษา รวมถึงภาษารัสเซีย ตลอดจนรูปแบบภาษาถิ่นจีนที่ผู้ผลิตระบุ ในระบบของผู้ผลิตต้องกำหนดเสียงเมื่ออัปเดตการตั้งค่าเซสชันครั้งแรก การส่งเสียงใหม่ภายหลังในการสนทนาเดียวกันจะถูกละเลย การตั้งค่าเหล่านี้ต้องได้รับการรองรับจากวิธีเรียกใช้ที่เลือก\n\n### เครื่องมือและประวัติการสนทนา\n\nรองรับการเรียกฟังก์ชัน โมเดลระบุการกระทำที่ต้องการ จากนั้นแอปพลิเคชันที่เชื่อมต่อจะดำเนินการและส่งผลกลับเข้าบทสนทนา ทำให้สามารถสนทนาโดยอ้างอิงข้อมูลจริง และดำเนินต่อหลังทำรายการแล้ว ผู้ช่วยเสียงสามารถใช้ผลจากเครื่องมือเป็นข้อมูลอ้างอิงพร้อมรักษาบริบทของการสนทนา ความสามารถของผู้ผลิตยังรวมถึงการค้นหาเว็บในตัว หากวิธีที่เลือกใช้รองรับ แต่ไม่สามารถเปิดการค้นหาเว็บและการเรียกฟังก์ชันพร้อมกันในเซสชันเดียวได้\n\nประวัติการสนทนามี 20 รอบโดยค่าเริ่มต้น และกำหนดได้ตั้งแต่หนึ่งถึง 50 รอบ เสียงที่สะสมไว้มีขีดจำกัด 300 วินาที เมื่อเกินขีดจำกัด ระบบจะลบส่วนเก่าของประวัติออก ข้อจำกัดนี้ต่างจากระยะเวลาของคำพูดแต่ละครั้ง เพราะประวัติเป็นตัวกำหนดว่าข้อมูลก่อนหน้านี้ส่วนใดยังใช้ได้เมื่อสนทนาต่อ\n\n### บริบทข้อความและเสียง\n\nขนาดบริบทตามข้อกำหนดคือ 40 960 โทเคน ความยาวอินพุตสูงสุดคือ 16 384 โทเคน และเอาต์พุตสูงสุด 8192 โทเคน โหมดใช้เหตุผลระบุขีดจำกัดอินพุตและเอาต์พุตเท่ากัน โดยมีขีดจำกัดสายการให้เหตุผลแยกต่างหากที่ 1024 โทเคน\n\nเสียงแบบสตรีมใช้ PCM หนึ่งช่องสัญญาณแบบ 16 บิต โดยอินพุตมีอัตรา 16 kHz และเอาต์พุต 24 kHz ข้อความและข้อมูลเสียงอยู่ในบทสนทนาเดียวกัน สำหรับโมเดลนี้โดยเฉพาะ ยังไม่มีการระบุอินพุตภาพหรือเอาต์พุตภาพ ความเชี่ยวชาญของโมเดลคือเสียงพูด ข้อความ และการโต้ตอบด้วยเสียง",
    "alias_of": null,
    "aliases": [],
    "author": "Alibaba",
    "ctx": null,
    "formats": [
      "realtime"
    ],
    "id": "qwen-audio-3.0-realtime-plus",
    "input": [
      "text",
      "audio"
    ],
    "kind": "speech",
    "max_out": null,
    "methods": [
      {
        "cache_read": null,
        "cache_write": null,
        "cache_write_1h": null,
        "cache_write_5m": null,
        "conditional_meter": null,
        "contract": {
          "data": {
            "all_results": "ประกอบข้อมูลเสียงส่วนเพิ่มและผลลัพธ์ข้อความ/เหตุการณ์ทั้งหมดที่ส่งกลับสำหรับ ID การตอบกลับจริงแต่ละรายการ",
            "endpoint": {
              "http": "GET",
              "path": "/v1/realtime",
              "query": {
                "model": "qwen-audio-3.0-realtime-plus"
              },
              "transport": "WebSocket",
              "url": "wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus"
            },
            "errors": [
              {
                "condition": "ไม่มีการอัปเกรด WebSocket",
                "http_status": 426,
                "recovery": "ใช้ไคลเอนต์ WebSocket พร้อม Upgrade: websocket",
                "type": "invalid_request_error"
              }
            ],
            "hints": [
              "Append the model query once; do not add another ?model to a URL that already contains it.",
              "Use the actual WebSocket upgrade and API-key authentication.",
              "Tools, web search and voiceprint enhancement are not supported on this exact route."
            ],
            "ignored_fields": [],
            "lifecycle": {
              "close": "Close the actual establishedWebSocket session; no fakeHTTP cancelpath.",
              "mode": "WebSocket session",
              "unknown": "เก็บ ID เซสชัน/การตอบกลับ/เหตุการณ์จริงและหลักฐานบันทึก"
            },
            "material_combinations": [
              {
                "events": [
                  "session.update",
                  "input_audio_buffer.append",
                  "input_audio_buffer.commit",
                  "input_audio_buffer.clear",
                  "response.create",
                  "response.cancel",
                  "conversation.item.create",
                  "conversation.item.retrieve",
                  "conversation.item.delete"
                ],
                "mode": "realtime_text_audio"
              }
            ],
            "operation_modes": [
              "realtime_text_audio"
            ],
            "outputs": {
              "all_outputs": "Assemble every returned audio delta and text/event result for each actual response ID.",
              "audio_format": "PCM16 mono 24 kHz",
              "family": [
                "text",
                "audio"
              ],
              "format": "เหตุการณ์ของเซสชัน"
            },
            "parameters": [
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "qwen-audio-3.0-realtime-plus"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "query.model",
                "required": true,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "pcm16",
                  "pcm"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "session.input_audio_format",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": [
                  "pcm16",
                  "pcm"
                ],
                "enum_known": true,
                "enum_status": "specified",
                "name": "session.output_audio_format",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "limit_scope": "นโยบายเซสชันที่เลือก",
                "name": "session.instructions",
                "required": false,
                "type": "string"
              },
              {
                "availability": "source_interface",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "limit_scope": "นโยบายเซสชันที่เลือก",
                "minimum": 1,
                "name": "session.max_history_turns",
                "required": false,
                "type": "integer"
              },
              {
                "availability": "source_interface",
                "content": "PCM16 แบบโมโน ขาเข้า 16 kHz ขาออก 24 kHz ความยาวไบต์ต้องไม่เป็นศูนย์และเป็นจำนวนคู่",
                "default": null,
                "default_known": false,
                "default_status": "not_specified",
                "enum": null,
                "enum_known": false,
                "enum_status": "not_specified",
                "name": "input_audio_buffer.append.audio",
                "required": true,
                "type": "base64_string"
              }
            ],
            "unsupported": []
          },
          "hints": [
            "รูปแบบเมธอดและ ID ระบุอย่างแม่นยำ ความสามารถของผู้ให้บริการแยกจากการอนุญาตให้รับคำขอ"
          ],
          "input": {
            "content_type": "WebSocket",
            "material_types": [
              "text",
              "audio"
            ],
            "optional_controls": null,
            "required": null
          },
          "lifecycle": {
            "mode": "exact retained published method"
          },
          "method": {
            "http": "GET",
            "path": "/v1/realtime?model=qwen-audio-3.0-realtime-plus"
          },
          "operation_modes": [
            "realtime"
          ],
          "output": {
            "family": [
              "text",
              "audio"
            ],
            "format": "session events",
            "multioutputs": "retain every actual response output"
          }
        },
        "ctx": null,
        "examples": [
          {
            "code": "# Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(\"AILOOT_API_KEY\", \"\")\nif not key.strip():\n    raise SystemExit(\"Set your AILOOT_API_KEY before connecting\")\nfile = Path(os.environ.get(\"AILOOT_TEXT_FILE\", \"\"))\nif not file.is_file(): raise SystemExit(\"Set AILOOT_TEXT_FILE to your actual UTF-8 material\")\nmaterial = file.read_text(encoding=\"utf-8\")\nif not material.strip(): raise SystemExit(\"Text material must not be empty\")\nout = Path(\"realtime-results\")\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left <= 0:\n        raise TimeoutError(\"Client session limit; preserve IDs and partial results, do not replay\")\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n    log.flush()\n    kind = event.get(\"type\")\n    if kind == \"error\":\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == \"response.created\":\n        current_response = event[\"response\"][\"id\"]\n    if kind in {\"response.audio.delta\", \"response.output_audio.delta\", \"response.text.delta\", \"response.output_text.delta\", \"response.audio_transcript.delta\", \"response.output_audio_transcript.delta\", \"response.text.done\", \"response.audio_transcript.done\"}:\n        identity = (event[\"response_id\"], event[\"item_id\"], event[\"output_index\"], event[\"content_index\"])\n        if kind in {\"response.audio.delta\", \"response.output_audio.delta\"}:\n            raw = base64.b64decode(event[\"delta\"], validate=True)\n            if len(raw) % 2: raise ValueError(\"Output PCM16 chunk must have an even byte length\")\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(\".done\"):\n            texts[identity] = event.get(\"text\", event.get(\"transcript\", \"\"))\n        else:\n            texts[identity] = texts.get(identity, \"\") + event[\"delta\"]\n            print(event[\"delta\"], end=\"\", flush=True)\n    if kind == \"response.done\":\n        response = event[\"response\"]\n        complete.append(response)\n        if current_response is None: current_response = response[\"id\"]\n        if response[\"id\"] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(\"type\") == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(\"wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus\", additional_headers={\"Authorization\": \"Bearer \" + key}) as ws:\n        with (out / \"events.jsonl\").open(\"w\", encoding=\"utf-8\") as log:\n            wait_for(ws, log, \"session.created\")\n            send(ws, {\"type\":\"session.update\", \"session\":{\"modalities\":[\"audio\",\"text\"], \"input_audio_format\":\"pcm\", \"output_audio_format\":\"pcm\", \"turn_detection\":None}})\n            wait_for(ws, log, \"session.updated\")\n            send(ws, {\"type\":\"conversation.item.create\", \"item\":{\"type\":\"message\", \"role\":\"user\", \"content\":[{\"type\":\"input_text\", \"text\":material}]}})\n            send(ws, {\"type\":\"response.create\"})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {\"type\":\"response.cancel\"})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(\"status\") != \"completed\":\n        raise RuntimeError(\"Response did not complete normally; inspect saved events and status\")\nfinally:\n    manifest = {\"responses\":complete, \"parts\":[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {\"response_id\":identity[0], \"item_id\":identity[1], \"output_index\":identity[2], \"content_index\":identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (\"audio-\" + str(number) + \".pcm\")\n            wav_file = out / (\"audio-\" + str(number) + \".wav\")\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), \"wb\") as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({\"pcm\":str(pcm_file), \"wav\":str(wav_file), \"sample_rate_hz\":24000})\n        if identity in texts:\n            text_file = out / (\"text-\" + str(number) + \".txt\")\n            text_file.write_text(texts[identity], encoding=\"utf-8\")\n            record[\"text\"] = str(text_file)\n        manifest[\"parts\"].append(record)\n    (out / \"results.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    print(\"\\nSaved every received event and result in\", out)\n",
            "label": "Python WebSocket · text material and all text/audio results",
            "language": "python"
          },
          {
            "code": "# Install the documented client once: python3 -m pip install websockets\nimport base64, json, os, time, wave\nfrom pathlib import Path\nfrom websockets.sync.client import connect\n\nkey = os.environ.get(\"AILOOT_API_KEY\", \"\")\nif not key.strip():\n    raise SystemExit(\"Set your AILOOT_API_KEY before connecting\")\nfile = Path(os.environ.get(\"AILOOT_AUDIO_FILE\", \"\"))\nif not file.is_file(): raise SystemExit(\"Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording\")\nmaterial = file.read_bytes()\nif not material or len(material) % 2 or material.startswith(b\"RIFF\"):\n    raise SystemExit(\"Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header\")\nout = Path(\"realtime-results\")\nout.mkdir(exist_ok=True)\naudio, texts, complete = {}, {}, []\ncurrent_response = None\npending = False\ndeadline = time.monotonic() + 570  # Local client bound; lower server/session limits still apply.\n\ndef receive(ws, log):\n    global current_response, pending\n    left = deadline - time.monotonic()\n    if left <= 0:\n        raise TimeoutError(\"Client session limit; preserve IDs and partial results, do not replay\")\n    event = json.loads(ws.recv(timeout=min(60, left)))\n    log.write(json.dumps(event, ensure_ascii=False) + \"\\n\")\n    log.flush()\n    kind = event.get(\"type\")\n    if kind == \"error\":\n        raise RuntimeError(json.dumps(event, ensure_ascii=False))\n    if kind == \"response.created\":\n        current_response = event[\"response\"][\"id\"]\n    if kind in {\"response.audio.delta\", \"response.output_audio.delta\", \"response.text.delta\", \"response.output_text.delta\", \"response.audio_transcript.delta\", \"response.output_audio_transcript.delta\", \"response.text.done\", \"response.audio_transcript.done\"}:\n        identity = (event[\"response_id\"], event[\"item_id\"], event[\"output_index\"], event[\"content_index\"])\n        if kind in {\"response.audio.delta\", \"response.output_audio.delta\"}:\n            raw = base64.b64decode(event[\"delta\"], validate=True)\n            if len(raw) % 2: raise ValueError(\"Output PCM16 chunk must have an even byte length\")\n            audio.setdefault(identity, bytearray()).extend(raw)\n        elif kind.endswith(\".done\"):\n            texts[identity] = event.get(\"text\", event.get(\"transcript\", \"\"))\n        else:\n            texts[identity] = texts.get(identity, \"\") + event[\"delta\"]\n            print(event[\"delta\"], end=\"\", flush=True)\n    if kind == \"response.done\":\n        response = event[\"response\"]\n        complete.append(response)\n        if current_response is None: current_response = response[\"id\"]\n        if response[\"id\"] == current_response: pending = False\n    return event\n\ndef wait_for(ws, log, kind):\n    while True:\n        event = receive(ws, log)\n        if event.get(\"type\") == kind: return event\n\ndef send(ws, event):\n    ws.send(json.dumps(event, ensure_ascii=False))\n\ntry:\n    # One exact model query; no reconnect/retry loop and no provider credentials.\n    with connect(\"wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus\", additional_headers={\"Authorization\": \"Bearer \" + key}) as ws:\n        with (out / \"events.jsonl\").open(\"w\", encoding=\"utf-8\") as log:\n            wait_for(ws, log, \"session.created\")\n            send(ws, {\"type\":\"session.update\", \"session\":{\"modalities\":[\"audio\",\"text\"], \"input_audio_format\":\"pcm\", \"output_audio_format\":\"pcm\", \"turn_detection\":None}})\n            wait_for(ws, log, \"session.updated\")\n            for offset in range(0, len(material), 640):\n                send(ws, {\"type\":\"input_audio_buffer.append\", \"audio\":base64.b64encode(material[offset:offset+640]).decode(\"ascii\")})\n                time.sleep(0.02)\n            send(ws, {\"type\":\"input_audio_buffer.commit\"})\n            wait_for(ws, log, \"input_audio_buffer.committed\")\n            send(ws, {\"type\":\"response.create\"})\n            pending = True\n            try:\n                while pending: receive(ws, log)\n            except KeyboardInterrupt:\n                # Cancel the actual current inference, then preserve its returned status.\n                send(ws, {\"type\":\"response.cancel\"})\n                while pending: receive(ws, log)\n    if not complete or complete[-1].get(\"status\") != \"completed\":\n        raise RuntimeError(\"Response did not complete normally; inspect saved events and status\")\nfinally:\n    manifest = {\"responses\":complete, \"parts\":[]}\n    for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):\n        record = {\"response_id\":identity[0], \"item_id\":identity[1], \"output_index\":identity[2], \"content_index\":identity[3]}\n        if identity in audio:\n            raw = bytes(audio[identity])\n            pcm_file = out / (\"audio-\" + str(number) + \".pcm\")\n            wav_file = out / (\"audio-\" + str(number) + \".wav\")\n            pcm_file.write_bytes(raw)\n            with wave.open(str(wav_file), \"wb\") as wav:\n                wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)\n            record.update({\"pcm\":str(pcm_file), \"wav\":str(wav_file), \"sample_rate_hz\":24000})\n        if identity in texts:\n            text_file = out / (\"text-\" + str(number) + \".txt\")\n            text_file.write_text(texts[identity], encoding=\"utf-8\")\n            record[\"text\"] = str(text_file)\n        manifest[\"parts\"].append(record)\n    (out / \"results.json\").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n    print(\"\\nSaved every received event and result in\", out)\n",
            "label": "Python WebSocket · actual PCM recording and all results",
            "language": "python"
          }
        ],
        "family": "openai",
        "fast_multiplier": null,
        "flex_multiplier": null,
        "fmt": "realtime",
        "http": "GET",
        "img_in": null,
        "img_out": null,
        "in": 0.8,
        "input": [
          "text",
          "audio"
        ],
        "label": "เสียงแบบเรียลไทม์",
        "max_out": null,
        "max_tool_calls": null,
        "out": 6.4,
        "output": [
          "text",
          "audio"
        ],
        "path": "/v1/realtime?model=qwen-audio-3.0-realtime-plus",
        "pricing_profiles": [
          {
            "dimensions": {},
            "label": "Core",
            "units": [
              {
                "amount": 0.8,
                "amount_unit": "usd_per_million_tokens",
                "key": "in",
                "label": "Input",
                "side": "in"
              },
              {
                "amount": 6.4,
                "amount_unit": "usd_per_million_tokens",
                "key": "out",
                "label": "Output",
                "side": "out"
              },
              {
                "amount": 0.0048,
                "amount_unit": "usd_per_display_unit",
                "key": "audio_input_second",
                "label": "per minute of audio",
                "side": "in"
              },
              {
                "amount": 0.018,
                "amount_unit": "usd_per_display_unit",
                "key": "audio_output_second",
                "label": "per minute of output audio",
                "side": "out"
              }
            ]
          }
        ],
        "request_model_id": "qwen-audio-3.0-realtime-plus",
        "route_label": "Core",
        "status_reads": [],
        "tiers": [],
        "tool_prices": null,
        "unit": "conditional",
        "units": [
          {
            "key": "audio_input_second",
            "label": "per minute of audio",
            "side": "in",
            "usd": 0.0048
          },
          {
            "key": "audio_output_second",
            "label": "per minute of output audio",
            "side": "out",
            "usd": 0.018
          }
        ]
      }
    ],
    "model_aliases": [
      {
        "canonical_model_id": "qwen-audio-3.0-realtime-plus",
        "request_model_id": "qwen-audio-3.0-realtime-plus",
        "route_label": "Core"
      }
    ],
    "name": "qwen-audio-3.0-realtime-plus",
    "price": {
      "in": 0.8,
      "in_label": null,
      "out": 6.4,
      "out_label": null,
      "sort_in": 0.8,
      "sort_out": 6.4,
      "varies": false
    },
    "short": "โมเดลสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ แล้วตอบด้วยเสียงหรือข้อความ ออกแบบสำหรับจังหวะการสนทนาที่เป็นธรรมชาติและการทำงานร่วมกับเครื่องมือ"
  },
  "renderer_schema": {
    "method_order": "Original DTO methods order; every exact route/format/path/caller survives.",
    "prices": "Original public DTO fields and original native display HTML; no flattened or normalized offers."
  },
  "representation": "exact-public-dto-and-native-renderer-html",
  "representationNotes": {
    "current_reference": {
      "about_json_pointer": "/aboutHtml",
      "methods": [
        {
          "contract_json_pointer": "/methods/0/rawMethod/contract",
          "html_json_pointer": "/methods/0/html",
          "method_ordinal": 0
        }
      ],
      "role": "current-semantic-reference"
    },
    "raw_input": {
      "examples_role": "historical-input-not-current-ready-examples",
      "json_pointers": [
        "/rawModel",
        "/methods/0/rawMethod"
      ],
      "role": "historical-owner-input"
    },
    "schema": "ailoot-native-model-representations-v1"
  },
  "schema": "ailoot-static-model-facts-v1",
  "schema_version": 1,
  "shortText": "โมเดลสนทนาด้วยเสียงแบบสด รับเสียงพูดและข้อความ แล้วตอบด้วยเสียงหรือข้อความ ออกแบบสำหรับจังหวะการสนทนาที่เป็นธรรมชาติและการทำงานร่วมกับเครื่องมือ",
  "source": {
    "audit_sha256": "2e00086bcbfc28e64d0cebe97aa47c17d8d5618963027f8ffb9dc6123d7d25b1",
    "bridge_map_sha256": "1125275768b9636fc8461bc7da5061239a81ddfe508e2557843ca42c58ab0036",
    "raw_model_json_sha256": "c95275ed0ef241b409f46c5f30ba2c118876a44dce2b836eae74f05cd6e94277",
    "renderer_sha256": "890edb706fafafdd4f598bb324acf65fada58918b0911b97eb80e68be2ef65d9"
  },
  "sourceRevision": "468e5f8980e68509b946b89811a47661dfb1f23ae3c00ee9a4990875afca1dda"
}
