إنتقل إلى المحتوى الرئيسي

مواصفات بروتوكول بث أحداث SSE

تُرجع POST /chat/control/stream استجابة عبر الأحداث المرسلة من الخادم (text/event-stream): اتصال طويل الأمد يرسل نص الإجابة أثناء توليده، بالإضافة إلى أحداث منظَّمة للأماكن وإجراءات الخريطة والمسارات.

تحدد هذه الصفحة مواصفات ذلك البث. إذا كنت تستخدم kaleidr.js، فستقرأ لوحة الدردشة البث تلقائياً ولن تحتاج إلى هذه الصفحة. ارجع إليها عند إنشاء عميلك الخاص. تتوفر أمثلة عملاء جاهزة في Node وPython ضمن قراءة البث، وترد تفاصيل جسم الطلب في نقاط النهاية.

يستخدم /chat/summary/stream و/chat/button/stream تنسيق الإطارات نفسه، ولكن مع مجموعة أصغر من الأحداث. وترد تفاصيلهما في نهاية الصفحة.

قبل بدء البث​

لا يتحول الطلب المرفوض إلى بث مطلقاً. تؤدي أخطاء المصادقة أو نطاق الصلاحيات أو الحصة أو حدود المعدّل أو التحقق أو الحجم إلى استجابة HTTP عادية تحتوي على جسم JSON ورمز حالة من فئة 4xx (انظر الأخطاء). تحقّق من رمز الحالة أولاً، ولا تفسّر الجسم كبث SSE إلا إذا كانت الحالة 200.

تخضع الطلبات لحدود الحجم التالية: 400 رسالة كحد أقصى، و64,000 حرف لكل رسالة، و200,000 حرف لجميع الرسائل مجتمعة. يؤدي تجاوز أحد هذه الحدود إلى استجابة 422 مع رمز مثل conversation_too_long؛ أما تجاوز حجم الجسم 2 MiB فيؤدي إلى 413. ترد القائمة الكاملة في نقاط النهاية.

تتضمن الاستجابة الناجحة الترويسات التالية:

HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache, no-transform

تنسيق الإطارات​

يتكون الإطار من سطر أو سطرين يتبعهما سطر فارغ. وينتهي كل سطر بالرمز \n.

event: place
data: {"name": "Louvre Museum", "coordinates": {"lat": 48.8606, "lng": 2.3376}}

data: {"text": "The Louvre sits on the right bank"}

: keep-alive

  • الإطار المسمّى يتضمن سطر event: يتبعه سطر data:.
  • إطار النص يتضمن سطر data: فقط، ولا يحتوي على سطر event:.
  • التعليق يبدأ بنقطتين رأسيتين. يرسل Kaleidr الرمز : keep-alive بوصفه إشارة نبض للحفاظ على الاتصال، ولا يتضمن بيانات.
  • يحتوي data: دائماً على كائن JSON كامل في سطر واحد. يكون النص مرمّزاً باستخدام UTF-8.

لا تتطابق حدود مقاطع البيانات على الشبكة بالضرورة مع حدود الإطارات. فقد تُرجع عملية قراءة واحدة نصف إطار أو عدة إطارات. خزّن ما تتلقاه مؤقتاً، وقسّمه عند فواصل الأسطر، ولا تعالج الإطار إلا بعد الوصول إلى السطر الفارغ الذي ينهيه.

قاعدة التوافق​

تجاهل أسماء الأحداث غير المعروفة والحقول التي لا تستخدمها. يمكن إضافة أحداث وحقول جديدة إلى هذه المواصفات دون تغيير الإصدار. وسيتعطل العميل الذي يفشل عند ورود حدث غير معروف.

الأحداث المستقرة​

event:الحمولةالمعنى
(بلا اسم){ text }الجزء التالي من نص الإجابة. ألحِقه بالنص الموجود. قد يتضمن علامات [[Name]] حول أسماء الأماكن.
phase{ type: "phase", phase: "thinking", session_id }قُبل الطلب وبدأت المعالجة. تكون قيمة phase دائماً "thinking".
start{ type: "start", session_id, purpose: "control" }سيبدأ إرسال نص الإجابة.
place{ name, coordinates?: { lat, lng }, address?, category?, icon?, source?, id?, unverified? }مكان وارد في الإجابة. ادمج بحسب name، فأول إحداثيات تصل لكل اسم هي النهائية. يميز source: "vendor" مكاناً من بيانات المؤسسة الخاصة، وsource: "map" مكاناً تعرضه الخريطة المنشورة بالفعل.
place_linkedحقول المكان بالإضافة إلى is_update?تفاصيل إضافية عن مكان أُرسل سابقاً. ادمجها في المكان صاحب name نفسه، وتجاهلها إذا لم تتلقَّ ذلك المكان من قبل.
early_actions{ type: "early_actions", actions: [ { type, payload } ], places_count, is_partial: true }إجراءات خريطة يمكن تطبيقها قبل اكتمال الإجابة، وتُرسل بمجرد توفر إحداثيات لمكانين أو أكثر.
prompt_options{ type: "prompt_options", schema_version, kind, question, allow_free_text, options: [ { label, send_text } ] }سؤال يضم خيارات عند غموض الطلب. اعرض الخيارات وأرسل send_text المختار بصفته رسالة المستخدم التالية.
route_clear{}أزل المسارات المرسومة. ستصل مسارات جديدة بعدها.
route{ type: "route", schema_version, id?, profile, origin, destination, primary, alternatives[], comparison[], stops?, color?, label?, transit?, attribution? }مسار محسوب يصل قبل النص في أسئلة الاتجاهات، بحيث يمكن رسمه أثناء تدفق الإجابة.
end{ type: "end", full_text, places[], actions[], question_type, response_time, total_tokens?, dropped_places? }اكتملت الإجابة. هذه هي النتيجة المعتمدة.
error{ type: "error", message, code?, partial_text }فشلت الإجابة. يُرسل بدلاً من end.
quota{ type: "quota", product, meter, tier, used, limit, reset_at, period } باستخدام مفتاح الخادم؛ و{ type: "quota", meter, reset_at } باستخدام رمز الجلسةاستخدام أرصدة الذكاء الاصطناعي للمؤسسة بعد احتساب تكلفة الاتصال. وهو آخر حدث في البث، بعد end أو error. راجع quota.
: keep-aliveسطر تعليقإشارة نبض تُرسل بعد عشر ثوانٍ من السكون. تجاهل محتواها ولكن احتسبها نشاطاً.

أُزيل الحدث grounding بتاريخ (2026-09-05). ولم يعد يُرسل.

بطاقات البيانات المباشرة وطبقاتها​

قد تتضمن الأسئلة عن بيانات مباشرة أو قياسات أحد هذه الأحداث. تصل البطاقة قبل نص الإجابة، بينما قد تصل الطبقة أثناء النص أو بعده. وهي إضافات إلى الاستجابة: اعرض ما تدعمه وتجاهل الباقي. وقد تضاف حقول جديدة مستقبلاً.

event:الحمولةيُرسل من أجل
weather_cardكائن يحوي lat وlng وname ودرجات الحرارة (temp_c وtemp_f) وconditions وforecast[] اختيارياًالطقس الحالي في مكان.
weather_layerكائن يحوي layer وtile_path_template وtile_size وmax_zoom وscope وattributionطبقة تعرض درجات الحرارة فوق منطقة.
satellite_cardكائن يحوي name وnorad_id وlat وlng وaltitude_km وvelocity_kms وobserved_atموضع قمر صناعي محدد الاسم.
constellation_layerكائن يحوي group وfeatures[] لعناصر { name, norad_id, lat, lng } وtrack اختيارياًالأقمار الصناعية المحيطة بالقمر الموجود في البطاقة.
building_cardكائن يحوي lat وlng وname اختيارياً وheight_m وnum_floorsمعلومات عن مبنى.
trees_cardكائن يحوي lat وlng وcount وradius_mالأشجار التي شملها المسح حول نقطة.
heritage_cardكائن يحوي lat وlng وcount وsites[]مواقع التراث حول نقطة.
rail_cardكائن يحوي lat وlng وlines[] وnearest_station اختيارياًخطوط السكك الحديدية قرب نقطة.
arrivals_cardكائن يحوي lat وlng وstop وdepartures[] وalerts[] وattributionمواعيد مغادرة النقل العام من محطة.
vehicles_layerكائن يحوي operator وvehicles[] وshapes[] وattributionمواقع مركبات النقل العام التابعة للمحطة أو الخط في البطاقة.
streetview_cardكائن يحوي lat وlng وimage_id وimage_lat وimage_lngصور على مستوى الشارع قرب مكان.

عند إرسال هذه الأحداث، يكرر end خمسة منها بالأسماء نفسها حتى يتمكن العميل الذي فاته الحدث من قراءتها: weather_card وsatellite_card وconstellation_layer وweather_layer وvehicles_layer (مثل end.weather_card). لا تتكرر البطاقات الأخرى في end. لا تتوفر قوائم الفعاليات المباشرة من خلال واجهة برمجة تطبيقات المنصة؛ راجع تراخيص البيانات.

أحداث التشخيص والتجارب (خارج المواصفات الملزمة)​

قد تظهر هذه الأحداث في البيانات المرسلة، لكنها ليست جزءاً من المواصفات المعتمدة؛ فلا تعتمد عليها.

event:الحمولةملاحظات
debug{ scope, … }تشخيص داخلي. لا يُرسل في الطلبات المعتادة.
place_name_found{ name, is_early }إشارة مبكرة إلى ذكر اسم مكان. استخدم حدث place الذي يأتي بعدها.

ترتيب الأحداث​

يمر البث بالمراحل التالية. المراحل الموسومة بأنها اختيارية لا تظهر في جميع عمليات البث.

  1. اختياري. أحداث place التي تحمل source: "vendor": ما يصل إلى ثلاثة أماكن من بيانات مؤسستك الخاصة عندما يمتلك المفتاح النطاق vendor. تُرسل أولاً لتتمكن الخريطة من رسمها فوراً.
  2. phase. يكون دائماً أول حدث من الإجابة نفسها.
  3. اختياري. تعليقات : keep-alive أثناء إعداد الإجابة.
  4. اختياري. أحداث تسبق النص: prompt_options، أو route_clear يليه route، مع بطاقة.
  5. start.
  6. إطارات النص تتخللها أحداث place وplace_linked وearly_actions، وأحياناً route_clear وroute وأحداث الطبقات. وتسد إشارات إبقاء الاتصال فترات السكون.
  7. اختياري. أحداث متأخرة من place وplace_linked والطبقات والمسارات بعد اكتمال النص.
  8. end أو error.
  9. اختياري. quota.
  10. يغلق الخادم الاتصال.

تترتب على ذلك نتيجتان بالنسبة إلى العميل:

  • الحدث end ليس آخر حدث. استمر في القراءة حتى إغلاق جسم الاستجابة، وإلا فقد تفقد quota.
  • قد يُغلق البث من دون end أو error، مثلاً عند انقطاع الشبكة. اعتبر أي بث أُغلق من دون حدث إنهاء بثاً فاشلاً.

تفاصيل الحمولات​

النص والعلامات​

تحمل إطارات النص نصاً فقط، ولا تصل البيانات المنظَّمة داخل متن الإجابة مطلقاً. وقد يحتوي النص على علامات بأقواس مربعة مزدوجة حول أسماء الأماكن، مثل near [[Louvre Museum]]، وتحولها لوحة الدردشة إلى روابط لدبابيس الخريطة. عند العرض كنص عادي، أزل الأقواس واحتفظ بالاسم.

place​

الحقلالنوعملاحظات
namestringالمفتاح الذي يُستخدم للدمج.
coordinatesobject { lat, lng }درجات عشرية. قد يكون غائباً. يُرسل المكان الذي تعذر تحديد موقعه دون إحداثيات ومع unverified: true. لا ترسم دبوساً له.
addressstringاختياري.
categorystringاختياري.
iconstringاختياري. رمز تعبيري للمكان.
sourcestringاختياري. تشير "vendor" إلى مكان من بيانات مؤسستك الخاصة. وتشير "map" إلى مكان تعرضه الخريطة المنشورة التي يشاهدها الزائر بالفعل؛ لا تضيف لوحة الدردشة دبوساً آخر لأن الخريطة ترسمه.
idstringاختياري. يوجد في الأماكن الواردة من بياناتك الخاصة.
unverifiedbooleanاختياري. تكون القيمة true عندما لا يكون موقع المكان مؤكداً.

قد يحتوي المكان على حقول إضافية. تجاهل ما لا تستخدمه منها.

قد يصل الاسم نفسه أكثر من مرة: أولاً مع الإحداثيات، ثم مع مزيد من التفاصيل. احتفظ بسجل واحد لكل اسم، ولا تحرّك دبوساً بعد حصوله على إحداثيات، ودع الأحداث اللاحقة تكمل الحقول الأخرى.

الإجراءات​

early_actions.actions وend.actions قائمتان من عناصر { type, payload }.

نوع الإجراءالحمولةالمطلوب
map.fitBounds{ coordinates: [[lng, lat], …], padding, maxZoom, duration }اضبط عرض الكاميرا لاحتواء الإحداثيات.
places.highlight{ places: [ { name, lat, lng } ], options }أبرز هذه الأماكن.
map.showRoute{ id, label, profile, coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[], transit?, attribution? }ارسم الخط واعرض attribution المرتبط به.
route.clear{ id? }أزل المسار صاحب id، أو جميع المسارات إذا لم يُحدد id.

قد تظهر أنواع إجراءات أخرى؛ فتجاوز ما لا تدعمه. انتبه إلى شكلَي الإحداثيات: يحمل المكان coordinates: { lat, lng }، أما الخط فهو قائمة من الأزواج [lng, lat].

route​

يحتوي primary على الخط المطلوب رسمه: { coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[] }. تتضمن كل خطوة في turn_by_turn الحقل text، وقد تتضمن أيضاً direction_type وdistance_m وduration_s وlat وlng. يمتلك كل من origin وdestination حقلاً باسم label. يحمل alternatives[] خطوطاً أخرى تتضمن route_id، بينما يبين comparison[] قيمة delta_duration_s لكل بديل مقارنة بالمسار الأساسي. وعند وجود stops[]، فإنه يحتوي على نقاط { lat, lng, name } مرتبة لمسار متعدد المحطات.

يحمل مسار الطرق attribution: { text, url, license }. اعرض text مع رابط إلى url حيثما ترسم المسار. أما مسار النقل العام فترد معلومات نسبته إلى المشغّل داخل transit بدلاً من ذلك.

يحمل كل حدث route معرّف id. ويؤدي رسم مسار بمعرّف id موجود مسبقاً إلى استبدال ذلك المسار.

end​

الحقلالنوعملاحظات
full_textstringالإجابة الكاملة. فضّلها على النص الذي جمّعته من إطارات متتابعة.
placesarrayقائمة الأماكن النهائية مرتبة. ادمجها بحسب الاسم مع الأماكن التي جمعتها.
actionsarrayإجراءات الخريطة النهائية. طبّقها لأنها تحل محل early_actions.
dropped_placesarray of stringsاختياري. أسماء أُرسلت سابقاً ولم تعد جزءاً من الإجابة النهائية. أزل دبابيسها.
question_typestringتسمية تصف نوع السؤال لأغراض إعلامية فقط.
response_timenumberالزمن الذي استغرقته الإجابة بالثواني.
total_tokensnumberاختياري. عدد الرموز المستخدمة في الإجابة، وهو أساس احتساب التكلفة.

error​

event: error
data: {"type": "error", "code": "upstream_stall", "message": "The AI service stopped responding. Please try again.", "partial_text": "The Louvre sits"}

يمكن عرض message للمستخدم مباشرة. أما partial_text فهو النص الذي أُنتج قبل الفشل. ولا يظهر code إلا في حالة واحدة:

الحالةcodeالمطلوب
توقف تقدم الإجابة أو بلغ البث أقصى طول له"upstream_stall"قدّم خيار إعادة المحاولة.
أي فشل آخر أثناء الإجابةغير موجوداعرض message، فقد تنجح إعادة المحاولة.

لا يأتي end بعد error، لكن قد يتبعه حدث quota.

quota​

تعتمد الحقول على بيانات الاعتماد التي فتحت البث.

الحقلالنوعمفتاح الخادم أو المفتاح القديمرمز الجلسة
typeسلسلة نصية, "quota"نعمنعم
meterسلسلة نصيةنعمنعم
reset_atسلسلة، ISO 8601 مع إزاحة زمنيةنعمنعم
productسلسلة نصيةنعملا
periodسلسلة نصيةنعملا
tierسلسلة نصيةنعملا
usedعددنعملا
limitعددنعملا

رمز الجلسة هو ما يستخدمه زوار الصفحة، سواء جرى الحصول عليه بتبادل مفتاح قابل للنشر أو من جلسة زائر لخريطة منشورة. لا يبيّن حدث quota الخاص به سوى موعد إعادة ضبط الفترة، ولا يكشف خطة المؤسسة أو استخدامها أو حدها. يجب ألا يفترض عميل المتصفح وجود used أو limit. وتنطبق القاعدة نفسها على جسم استجابة 429 quota_exceeded؛ راجع الحصص وحدود المعدّل.

إبقاء الاتصال والمهلات​

السلوكالقيمةما يجب على العميل فعله
إشارة نبض في بث الدردشةتعليق : keep-alive بعد عشر ثوانٍ دون أي إخراج آخرأعد ضبط مؤقت الخمول عند تلقي أي بايت، بما في ذلك التعليقات.
اتصال خاملقد يُغلق اتصال لم يرسل شيئاً لنحو دقيقة أثناء النقلاضبط مهلة الخمول (القراءة) بين 30 و60 ثانية. لا تضع مهلة قصيرة لإجمالي الوقت.
الوقت حتى أول نصقد يستغرق عشرات الثواني في الأسئلة الصعبةاعرض تقدماً من حدث phase، ولا تعتبر الانتظار فشلاً.
أقصى مدة للبثنحو عشر دقائق، ثم يرسل الخادم error مع upstream_stallاضبط مهلة إجمالية أطول قليلاً من عشر دقائق احتياطياً.

إيقاف البث واحتساب التكلفة​

أغلق الاتصال لإيقاف البث. يكتشف الخادم ذلك خلال نحو عشر ثوانٍ ويوقف إنشاء الإجابة.

  • يُحاسَب البث الذي يكتمل بنجاح وفق عدد الرموز المستخدمة في الإجابة كما ورد في end.total_tokens.
  • يُحاسَب البث الذي يتوقف أو يفشل قبل اكتماله وفق تقدير. لا يقل التقدير عن حجم المحادثة المرسلة في الطلب، أو يُحسب وفق النص الذي بُثّ بالفعل. لذلك قد تتجاوز التكلفة قيمة الحجز المبدئي الذي فُرض عند قبول الطلب: فإغلاق الاتصال بعد أول إطار لا يجعل المحادثة الطويلة مجانية.
  • لا تُحسب الأماكن الواردة من بياناتك الخاصة (source: "vendor") ضمن التكلفة.

إعادة المحاولة طلب جديد وتُحتسب تكلفته من جديد. راجع الحصص وحدود المعدّل.

بث الملخصات والأزرار​

تدعم نقطتا النهاية هاتان بطاقة المكان في Kaleidr Chat. وتستخدمان تنسيق الإطارات نفسه وإطارات النص غير المسماة وحدث quota النهائي نفسه. وتختلفان عن بث الدردشة في ثلاثة أمور: لا ترسلان حدث phase، ولا أحداث الأماكن أو الإجراءات، ولا ترسلان إشارات إبقاء الاتصال. استخدم مهلة خمول قدرها 60 ثانية.

ترفض كلتا نقطتَي النهاية الحقول الطويلة جداً قبل بدء البث بالحالة 422 والرمز field_too_long، وتتجاهلان الحقول غير المدرجة؛ راجع نقاط النهاية. عند إيقاف أحد هذين البثين أو فشله، تعتمد التكلفة على تقدير النص الذي أُرسل بالفعل ولا تتجاوز الحجز المبدئي.

POST /chat/summary/stream، لمكان:

  1. اختياري. address بالحمولة { type: "address", address, source }
  2. start بالحمولة { type: "start", poi_type }
  3. اختياري وقد يتكرر. url بالحمولة { type: "url", website, source }
  4. إطارات نصية بالحمولة { text }
  5. end بالحمولة { type: "end", full_text, summary, poi_type, category, city, country, sources[], website?, total_tokens? }، أو error بالحمولة { type: "error", message, partial_text }
  6. اختياري. quota

POST /chat/summary/stream، لمبنى (type: "building"):

  1. start بالحمولة { type: "start", address }
  2. إطارات نصية
  3. end بالحمولة { type: "end", full_text, parsed, total_tokens? }، أو error
  4. اختياري. quota

POST /chat/button/stream:

  1. start بالحمولة { type: "start", query_type }
  2. إطارات نصية
  3. end بالحمولة { type: "end", full_text, reply, query_type, first_token_ms, total_ms, total_tokens? }
  4. اختياري. quota

لا يتضمن بث الأزرار حدث error. وإذا فشل بعد أن يبدأ، يُغلق الاتصال من دون end. أما الفشل قبل البدء فيُرجع HTTP 500 مع {"detail": "Button chat stream error"}.

POST /spot/overview/stream يرسل إطارات ملخص المكان الموضحة أعلاه، ويسبقها إطار place بالحمولة { type: "place", name }: الاسم الكامل للمكان أو المنطقة الموصوفة، مثل "Springfield, Ohio, United States of America"، لعرضه تسميةً أو نسخه. يصل قبل أي إطار آخر وقد يغيب. وهو ليس حدث place في تدفق الدردشة ولا يحمل إحداثيات. وإذا تعذر وصف ref، فإنه يرسل إطار error واحداً بالحمولة { type: "error", message, ref } بدلاً من الملخص. راجع نقاط النهاية.

صفحات ذات صلة​