दस्तावेज़
एक स्ट्रीमिंग सहायक क्लाइंट बनाएं
एक मोड़ खोलें, उसकी वास्तविक घटनाओं को प्रस्तुत करें, लंबित अनुरोधों का उत्तर दें, और टूटे हुए कनेक्शन के बाद बातचीत को पुनर्प्राप्त करें।
अंग्रेज़ी से स्वचालित रूप से अनुवादित। अंग्रेज़ी मूल देखें
चल रहे साइडकार से कनेक्ट करें
एक स्ट्रीमिंग सहायक क्लाइंट डेस्कटॉप के समान स्थानीय साइडकार से कनेक्ट होता है। जिस कनेक्शन के साथ आप एकीकृत कर रहे हैं, उससे उसका निर्दिष्ट लूपबैक यूआरएल और वर्तमान एप्लिकेशन बियरर टोकन प्राप्त करें। कल के लॉन्च से सहेजा गया पोर्ट एक टिकाऊ पता नहीं है: साइडकार हर बार शुरू होने पर एक अल्पकालिक पोर्ट का अनुरोध करता है। एक खाता सत्र टोकन, साथी जोड़ी टोकन और स्कोप्ड एक्शन-ब्रिज टोकन के अलग-अलग उद्देश्य हैं और इस चैट रूट पर एप्लिकेशन बियरर को प्रतिस्थापित नहीं कर सकते हैं।
टर्न सबमिट करने से पहले पढ़ें GET /api/ai/status, /api/ai/providers, और वैकल्पिक रूप से /api/ai/models?configuredOnly=true. कॉन्फ़िगर किए गए क्रेडेंशियल का अर्थ है कि एक कुंजी मौजूद है; यह साबित नहीं करता है कि प्रदाता अनुरोध स्वीकार करेगा या कोई समापन बिंदु चयनित मॉडल का समर्थन करता है। डिफ़ॉल्ट होस्ट एम्बेडेड निकल्ली है। डायरेक्ट मोड एक मॉडल उत्तर स्ट्रीम कर सकता है लेकिन एम्बेडेड होस्ट के लगातार टूल लूप या विशेषज्ञ शेड्यूलर की आपूर्ति नहीं करता है।
यह मार्गदर्शिका उपयोग करती है CADCAMFUN_URL और CADCAMFUN_TOKEN क्लाइंट-शेल वैरिएबल के रूप में। उन्हें अपने मौजूदा कनेक्शन हैंडलिंग के माध्यम से आपूर्ति करें। देखें एआई एपीआई संदर्भ सटीक स्कीमा के लिए और साइडकार लॉन्च व्यवहार के लिए. उदाहरण क्रेडेंशियल स्थापित नहीं करते हैं या आपकी ओर से कोई मॉडल नहीं चुनते हैं।
प्रोजेक्ट, ड्राइंग और सत्र पहचान चुनें
ग्राहक एक आपूर्ति कर सकता है sessionId इसके पहले मोड़ पर और बाद के मोड़ पर इसका पुन: उपयोग करें। सेवा उस क्लाइंट पहचानकर्ता को वास्तविक होस्ट सत्र में मैप करती है और प्रत्येक संकेत से पहले बाइंडिंग की जांच करती है। हर बार यूआई पुनः कनेक्ट होने पर एक अलग पहचानकर्ता बनाने के बजाय, इवेंट/सत्र की पहचान को वार्तालाप स्थिति के रूप में बनाए रखें।
एक असली projectId उस प्रोजेक्ट के अनुमत संसाधनों तक पहुंच प्रदान करता है। एक वैकल्पिक drawingId उस प्रोजेक्ट से संबंधित होना चाहिए; यह टर्न के टूल को उस ड्राइंग से जोड़ता है। किसी चित्र का नाम उसके प्रोजेक्ट के बिना नहीं दिया जा सकता। पहले से ही किसी अन्य खाते या प्रोजेक्ट के स्वामित्व वाले सत्र को अस्वीकार कर दिया गया है। मॉडल द्वारा प्रोजेक्ट टूल निष्पादित करने से पहले ये प्रवेश जांच हैं, सिस्टम प्रॉम्प्ट में संकेत नहीं।
सामान्य व्याख्यात्मक बातचीत के लिए, प्रोजेक्ट और ड्राइंग को छोड़ दें। एप्लिकेशन अपने डिफ़ॉल्ट संदर्भ का उपयोग करता है। ज्यामिति कार्य के लिए, वास्तविक चयनित प्रोजेक्ट/ड्राइंग आईडी को चैट, राज्य पुनर्प्राप्ति, कतार, निरस्त और नियंत्रण अनुरोधों के माध्यम से ले जाएं। खाता स्विच को पिछले खाते के सक्रिय सत्र को चुपचाप नहीं अपनाना चाहिए।
स्ट्रीमिंग टर्न सबमिट करें
POST /api/ai/chat/stream एक SSE निकाय लौटाता है। इसके लिए एक गैर-रिक्त संदेश की आवश्यकता होती है, भले ही ट्रांसपोर्ट स्कीमा कई फ़ील्ड को वैकल्पिक बनाती है ताकि हैंडलर पढ़ने योग्य सत्यापन संदेश लौटा सकें। निम्नलिखित सामान्य प्रश्न संग्रहीत संदर्भ इंजेक्शन को अक्षम कर देता है, जिससे यह परियोजना ज्यामिति से स्वतंत्र रूप से परिवहन की जांच करने के लिए उपयुक्त हो जाता है।
curl --no-buffer --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"message":"Explain the difference between G0 and G1.","sessionId":"inspection-demo","includeContext":false,"mode":"gcode"}' \
"$CADCAMFUN_URL/api/ai/chat/stream" जोड़ना projectId और drawingId एक विशिष्ट ड्राइंग पर काम करने के लिए. mode सामान्य, सीएडी, कैम, जीकोड या टूलपाथ स्वीकार करता है। ए model चयनकर्ता में प्रदाता, मॉडल, स्तर और प्रकार शामिल हो सकते हैं; स्तर तेज़, संतुलित या सर्वोत्तम हैं। कौन सा विक्रेता उपलब्ध है, इसके बारे में हार्ड-कोडिंग करने के बजाय चल रहे कैटलॉग से प्रदाता/मॉडल आईडी खोजें।
permissionMode अनुमोदन, पूछना, या ऑटो स्वीकार करता है। विनाशकारी उपकरण समूह हर मोड में मानवीय स्वीकृति बनाए रखते हैं। agent फ़ील्ड एक कॉन्फ़िगर की गई सहायक भूमिका का चयन करती है; पढ़ना GET /api/ai/agents भूमिका आईडी का अनुमान लगाने के बजाय।
संपूर्ण एसएसई डेटा फ़्रेम पढ़ें
मार्ग इफ़ेक्ट के SSE डेटा मोड का उपयोग करता है: प्रत्येक SSE डेटा पेलोड एक JSON ईवेंट रिकॉर्ड है type विभेदक नेटवर्क खंड कोई ईवेंट सीमा नहीं है. JSON, पंक्ति अंत और UTF-8 वर्णों को पढ़ने के बीच विभाजित किया जा सकता है। डिकोड किए गए टेक्स्ट को संचित करें और केवल पूर्ण फ़्रेमों को पार्स करें, मौजूद होने पर कई डेटा लाइनों को जोड़ें।
async function* events(response: Response): AsyncGenerator<Record<string, unknown>> {
if (!response.ok) throw new Error(await response.text())
if (!response.body) throw new Error("The response has no stream")
const reader = response.body.getReader()
const decoder = new TextDecoder()
let pending = ""
try {
while (true) {
const next = await reader.read()
pending += decoder.decode(next.value, { stream: !next.done })
let boundary: RegExpExecArray | null
while ((boundary = /\r?\n\r?\n/.exec(pending)) !== null) {
const frame = pending.slice(0, boundary.index)
pending = pending.slice(boundary.index + boundary[0].length)
const data = frame.split(/\r?\n/)
.filter((line) => line.startsWith("data:"))
.map((line) => line.slice(5).replace(/^ /, "")).join("\n")
if (!data) continue
const event: unknown = JSON.parse(data)
if (!event || typeof event !== "object" || !("type" in event)) {
throw new Error("Invalid assistant event")
}
yield event as Record<string, unknown>
}
if (next.done) break
}
} finally {
await reader.cancel().catch(() => {})
reader.releaseLock()
}
} यह पाठक फ़्रेमिंग प्रदर्शित करता है; एक प्रोडक्शन क्लाइंट को प्रत्येक ईवेंट को साझा अनुबंध के विरुद्ध सत्यापित करना चाहिए या टाइप किए गए जेनरेटेड स्ट्रीमिंग क्लाइंट का उपयोग करना चाहिए। यह जानबूझकर SSE टिप्पणी/नियंत्रण फ़ील्ड को अनदेखा करता है क्योंकि इस समापन बिंदु की एप्लिकेशन स्थिति JSON डेटा रिकॉर्ड में रहती है। क्लाइंट स्ट्रीम जारी करना ट्रांसपोर्ट क्लीनअप है, सर्वर-साइड कार्य को निरस्त करने का स्पष्ट अनुरोध नहीं।
सामग्री की नकल किए बिना प्रगति प्रस्तुत करें
ऊपर दिखाए गए समान बियरर और JSON बॉडी के साथ फ़ेच शुरू करें, फिर रीडर को पुनरावृत्त करें। संलग्न delta.text दृश्यमान उत्तर पाठ और रूट के लिए reasoning.text अपने स्वयं के दृष्टिकोण के लिए. ए done घटना में अंतिम प्रतिक्रिया पाठ होता है; संपूर्ण उत्तर को दोबारा जोड़ने के बजाय संचित उत्तर को उस अंतिम मान से बदलें या उसका मिलान करें।
| घटनाएँ | बनाए रखने के लिए राज्य |
|---|---|
turn, session_status, step | व्यस्त/पुनःप्रयास स्थिति और वर्तमान चरण; एक चरण की समाप्ति के बाद उसी चरण में दूसरा चरण किया जा सकता है। |
tool_call, tool_progress, tool_result | नाम, इनपुट, तर्क प्रगति, आउटपुट और सफलता के साथ कॉलआईडी द्वारा एक रिकॉर्ड; उपस्थित होने पर एजेंट किसी विशेषज्ञ की पहचान करता है। |
tool_diagnostic | तर्क/निष्पादन/आंशिक/सत्यापन निष्कर्ष, गंभीरता, पुनर्प्राप्ति पाठ, और वैकल्पिक उत्परिवर्तन लागू। |
todo, goal | बार-बार प्रतियां जोड़ने के बजाय वर्तमान योजना/लक्ष्य स्नैपशॉट को बदलें। |
retry, compaction, compacted | वार्तालाप के वर्तमान पाठ और सत्र की पहचान को संरक्षित करते हुए निरंतर कार्य की व्याख्या करें। |
heartbeat | कोई दृश्य सामग्री नहीं; जब स्रोत स्ट्रीम सक्रिय रहती है तो सर्वर लगभग हर पाँच सेकंड में एक भेजता है। |
टूल कॉल और परिणामों को सहसंबंधित करें callId, उनकी सरणी स्थिति नहीं। एक विफल उपकरण उपयोगी निदान लौटा सकता है जबकि सहायक जारी रहता है। एक सफल संपादन उपकरण के बाद प्रदाता की त्रुटि उस ज्यामिति परिवर्तन को वापस नहीं लाती है।
अनुमतियों और प्रश्नों का उत्तर दें
A permission_request इसमें sessionId, requestId, अनुमति और पैटर्न शामिल हैं। व्यक्ति को अनुरोध प्रस्तुत करें और चयनित निर्णय भेजें POST /api/ai/permission/reply. समतुल्य सत्र-नियंत्रण क्रिया है reply_permission. सर्वर सत्यापित करता है कि अनुरोध अभी भी वार्तालाप या स्वीकृत चाइल्ड सत्र में लंबित है।
{
"sessionId": "inspection-demo",
"requestId": "request-id-from-the-event",
"decision": "once"
} निर्णय एक बार, हमेशा, या अस्वीकार है। यह एक सर्वर अनुमति निर्णय है, जो पुष्टि जैसे कार्रवाई तर्क से अलग है। एक लंबित question_request इसमें क्रमबद्ध प्रश्नों की एक श्रृंखला शामिल है। के माध्यम से उत्तर दें /api/ai/sessions/control कार्रवाई के साथ answer_question, अनुरोध आईडी, और प्रति प्रश्न एक उत्तर सरणी; इसे अस्वीकार करें reject_question.
{
"sessionId": "inspection-demo",
"action": "answer_question",
"requestId": "question-id-from-the-event",
"answers": [["The selected option label"]]
} प्रत्येक उत्तर गैर-रिक्त होना चाहिए. एक एकल-विकल्प वाला प्रश्न एकाधिक उत्तरों को अस्वीकार करता है, और कस्टम=गलत केवल सूचीबद्ध लेबल की अनुमति देता है। सटीक लेबल और प्रश्न क्रम सुरक्षित रखें। यदि सर्वर कहता है कि अनुरोध अब लंबित नहीं है, तो पुराने उत्तर को बार-बार पोस्ट करने के बजाय नियंत्रण ताज़ा करें।
कतार में लगना, संचालन करना और स्पष्ट रूप से काम बंद करना
उपयोग POST /api/ai/chat/queue टर्न के काम करने के दौरान सबमिट किए गए संदेश के लिए। इसमें सेशनआईडी, संदेश, वैकल्पिक प्रोजेक्टआईडी और डिलीवरी की आवश्यकता होती है। queue डिफ़ॉल्ट है और अगले सुरक्षित चरण की प्रतीक्षा करता है; steer मेज़बान से इसे तुरंत शामिल करने के लिए कहता है। ए user_message घटना संकेत देती है कि संदेश बातचीत में प्रवेश कर चुका है।
उपयोग POST /api/ai/chat/abort जब व्यक्ति स्टॉप दबाता है तो वार्तालाप पहचान के साथ। यह बारी को रोक देता है और अपने सहयोगी कार्यकर्ताओं से जुड़ जाता है। केवल फ़ेच रद्द करके स्टॉप लागू न करें: HTTP स्ट्रीम खोना समान ऑपरेशन नहीं है। एक सत्र नई परियोजना पहचान बनाए बिना एक और मोड़ स्वीकार कर सकता है।
POST /api/ai/sessions/remove अपने बच्चों को रद्द करने और शामिल करने के बाद मेजबान सत्र को हटा देता है। यह हटाए गए ध्वज को लौटाता है। किसी वार्तालाप को हटाना उसके टूल द्वारा किए गए प्रोजेक्ट संपादनों का रोलबैक नहीं है; आवश्यकता पड़ने पर प्रोजेक्ट/इतिहास एपीआई के माध्यम से उनकी समीक्षा करें या पुनर्स्थापित करें।
स्ट्रीम खोने के बाद पुनर्प्राप्त करें
जब पाठक बिना किसी अंतिम घटना के समाप्त हो जाता है, तो पूर्णता को अज्ञात मानें। पुकारना POST /api/ai/sessions/state समान sessionId और projectId के साथ। प्रतिक्रिया में वैकल्पिक पुनर्प्राप्त टूल/टूडू/डायग्नोस्टिक इवेंट, उपयोग और कार्यों के साथ व्यस्त और टेक्स्ट शामिल है। इस स्नैपशॉट से यूआई का पुनर्निर्माण करें; पुनर्प्राप्त टूल ईवेंट को दोबारा चलाने से वे दोबारा निष्पादित नहीं होते हैं।
फिर अनुरोध करें /api/ai/sessions/control लंबित अनुमतियों/प्रश्नों, कार्यकर्ता कार्यों, लक्ष्य और संदर्भ नीति का निरीक्षण करने के लिए कार्रवाई की स्थिति के साथ। किसी अनुत्तरित प्रश्न की प्रतीक्षा में व्यस्त व्यक्ति को उत्तर की आवश्यकता होती है, मूल संकेत की दूसरी प्रति की नहीं। संचित पाठ के साथ निष्क्रिय रिपोर्ट किए गए सत्र को पुनर्प्राप्त आउटपुट के रूप में प्रदर्शित किया जा सकता है, भले ही मूल टीसीपी कनेक्शन गायब हो गया हो।
नेटवर्क विफलता, टाइप किया गया प्रदाता/कॉन्फ़िगरेशन त्रुटि ईवेंट, स्पष्ट निरस्तीकरण और सत्र निष्कासन के बीच अंतर रखें। पहले मोड़ ने वास्तव में क्या किया, इसकी जाँच करने के बाद ही मॉडल अनुरोध को पुनः प्रयास करें। विशेष रूप से, आंशिक उत्परिवर्तन निदान या बाधित संपादन कार्यकर्ता के बाद वर्तमान ड्राइंग पढ़ें।
सर्वर के अंदर, एक गिरा हुआ मॉडल कनेक्शन 2-सेकंड बैकऑफ़ के साथ पांच बार तक फिर से शुरू किया जाता है जो कि 30 सेकंड तक दोगुना हो जाता है। स्ट्रीम से पुनः कनेक्ट होने वाले क्लाइंट को अभी भी सत्र स्थिति को पढ़ना चाहिए, क्योंकि वे रेज़्यूमे उस कार्य को पूरा कर सकते हैं जिसे क्लाइंट ने स्ट्रीम नहीं देखा था।
संदर्भ, अनुलग्नक, और संघनन
includeContext: false संग्रहीत संदर्भ का अधिग्रहण अक्षम करता है; उस मोड़ के लिए स्पष्ट संदर्भ पाठ अभी भी प्रदान किया जा सकता है। सामान्य असेंबली स्थायी आवश्यकताओं, वर्तमान अवलोकनों, यूआई स्नैपशॉट, मेमोरी और सहायक संदर्भों का आदेश देती है, उन्हें डुप्लिकेट करती है, और एक 24,000-वर्ण समग्र बजट लागू करती है। छोड़े गए/काटे गए ब्लॉकों की सूचना दी जाती है; यह बजट प्रदाता की टोकन विंडो नहीं है।
अनुलग्नकों में नाम, वैकल्पिक MIME, डेटा और वैकल्पिक पाठ/आधार64 एन्कोडिंग शामिल हैं। प्रति अनुरोध अधिकतम पाँच हैं। छवियाँ प्रत्येक 5 MiB तक, PDF 10 MiB तक, और पाठ 2,000,000 वर्णों तक सीमित हैं; 6,000 वर्णों तक का संक्षिप्त पाठ भी इनलाइन दिखाई देता है। टूल के लिए रखा गया टेक्स्ट मेमोरी में प्रोजेक्ट-स्कोप्ड है, इसलिए पुनः कनेक्ट करना सेवा को पुनरारंभ करने से अलग है। असमर्थित फ़ाइलें कारणों सहित अस्वीकृत कर दी जाती हैं।
नियंत्रण कार्रवाई संदर्भ एक विस्तृत टोकन ब्रेकडाउन का अनुरोध करता है; सामान्य स्थिति मतदान उस टोकननाइज़र कार्य से बचता है। एक्शन कॉम्पेक्ट मेज़बान से पुरानी बातचीत सामग्री को सारांशित करने के लिए कहता है। मेमोरी समेकन एक अलग होस्ट ऑपरेशन है। सटीक ज्यामिति को पुन: पेश करने के लिए एक संक्षिप्त बातचीत पर भरोसा करने के बजाय अपने स्वयं के एपीआई के माध्यम से स्रोत ड्राइंग और विनिर्माण अनुरोधों को जारी रखें।
डोमेन परिणामों से परिवहन त्रुटियों को अलग करें
HTTP 401 का मतलब है कि अनुरोध ने वाहक प्राधिकरण को पारित नहीं किया है। स्ट्रीमिंग से पहले 400 का मतलब आमतौर पर एक खाली संदेश, दुर्गम सत्र पहचान, अमान्य प्रोजेक्ट/ड्राइंग संयोजन, या विकृत बॉडी होता है। एक बार स्ट्रीम स्थापित हो जाने पर, हैंडलर कॉन्फ़िगरेशन, प्रदाता, निरस्त, या आंतरिक वर्गीकरण के साथ एक त्रुटि घटना उत्पन्न कर सकता है; उस घटना को तब भी संभालें, जब प्रतिक्रिया स्थिति 200 हो।
ok=false वाला टूल परिणाम एक टूल परिणाम है, जरूरी नहीं कि एक विफल स्ट्रीम हो। इसका आउटपुट और डायग्नोस्टिक दिखाएं ताकि सहायक या व्यक्ति ठीक हो सके। एक कार्यकर्ता कतार भी भरी हो सकती है: अनुसूचक चार सक्रिय और सोलह प्रतीक्षा कार्यों की अनुमति देता है। एक बाधित पाठक को सीमित प्रयासों के भीतर पुनर्प्राप्त किया जा सकता है; संपादन कार्य को स्वचालित रूप से दोबारा चलाने के बजाय अनिश्चित माना जाता है।
निष्पादन योग्य अनुबंधों को पढ़ें packages/api/src/groups/ai.ts और ai-events.ts; में प्रवेश और तार व्यवहार apps/sidecar/src/http/ai.ts; सत्र मानचित्रण packages/ai/src/service.ts; प्रश्न सत्यापन में nikcli/session-controls.ts; दिल की धड़कन का समय heartbeat.ts. ये स्रोत परिभाषित करते हैं कि ग्राहक को सहायक के गद्य से स्वतंत्र रूप से कौन सा परिणाम प्रस्तुत करना चाहिए।
घटना संदर्भ
प्रत्येक एसएसई data: फ़्रेम एक JSON ऑब्जेक्ट है type और ए sessionId. केवल पूर्ण फ़्रेम को पार्स करें; एक फ़्रेम नेटवर्क खंडों में विभाजित होकर आ सकता है।
| प्रकार | प्रमुख क्षेत्र | कैसे सम्हालें |
|---|---|---|
turn | phase: start, recovering, continuing, finish; वैकल्पिक reason | प्रगति स्थिति दिखाएँ. recovering इसका मतलब है कि मॉडल से कनेक्शन फिर से शुरू किया जा रहा है। |
session_status | status: busy, idle, retry | भेजें बटन और कतार को सक्षम या अक्षम करें। |
user_message | संग्रहीत उपयोगकर्ता संदेश | आशावादी यूआई का समाधान करें। |
delta | text | दृश्यमान उत्तर में जोड़ें. |
reasoning | तर्क पाठ | वैकल्पिक; एक संक्षिप्त क्षेत्र में दिखाएँ. |
step, todo, goal | योजना प्रगति | कार्य सूची या योजना प्रस्तुत करें. |
tool_call | callId, उपकरण, तर्क, वैकल्पिक agent | दिखाएँ कि कौन सा उपकरण चलता है और किस विशेषज्ञ के लिए। |
tool_progress | callId, प्रगति | लंबे समय से चल रहे टूल को अपडेट करें. |
tool_result | callId, परिणाम | परिणाम दिखाओ; इससे मिलान करें callId. |
tool_diagnostic | विवरण सहित mutationApplied | तय करें कि क्या मॉडल बदल गया है। किसी संपादन का पुनः प्रयास करने से पहले इसे पढ़ें. |
permission_request / permission_resolved / permission_blocked | requestId; जवाब once, always, reject | फिर, उपयोगकर्ता से पूछें POST /api/ai/permission/reply. |
question_request / question_resolved | प्रश्न डेटा | प्रश्न प्रस्तुत करें और उत्तर भेजें. |
context_snapshot, compaction, compacted | संदर्भ स्थिति | उपयोगकर्ता को सूचित करें कि पुराने इतिहास का सारांश दिया गया था। |
retry | attempt, message | एक क्षणिक सूचना दिखाएँ; संकेत पुनः न भेजें. |
done | text, वैकल्पिक usage, वैकल्पिक recovered | बारी का अंतिम पाठ. संचित डेल्टा को इसके साथ बदलें। |
error | code: provider, config, aborted, internal; message | संदेश के साथ यूआई में बदलाव समाप्त करें; config आमतौर पर इसका मतलब है लापता क्रेडेंशियल। |
heartbeat | कोई नहीं | प्रत्येक 5 सेकंड के बारे में जीवित रखें; अनदेखा करना। |
एक संपूर्ण स्ट्रीमिंग क्लाइंट
const base = process.env.CADCAMFUN_URL! // e.g. http://127.0.0.1:53211
const token = process.env.CADCAMFUN_TOKEN!
const response = await fetch(`${base}/api/ai/chat/stream`, {
method: "POST",
headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
body: JSON.stringify({ projectId: "p1", message: "Summarise this project", mode: "general" }),
})
if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`)
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader()
let buffer = "", answer = ""
for (;;) {
const { value, done } = await reader.read()
if (done) break
buffer += value
let end
while ((end = buffer.indexOf("\n\n")) >= 0) { // one SSE frame
const frame = buffer.slice(0, end); buffer = buffer.slice(end + 2)
const data = frame.split("\n").filter((l) => l.startsWith("data:"))
.map((l) => l.slice(5).trimStart()).join("\n")
if (!data) continue
const event = JSON.parse(data)
switch (event.type) {
case "delta": answer += event.text; break
case "permission_request": /* ask, then POST /api/ai/permission/reply */ break
case "done": answer = event.text; console.log(answer); break
case "error": throw new Error(`${event.code}: ${event.message}`)
}
}
} यदि कनेक्शन बंद हो जाता है, तो संदेश दोबारा न भेजें। के साथ सत्र पढ़ें POST /api/ai/sessions/state, क्योंकि हो सकता है कि सर्वर ने मॉडल कनेक्शन फिर से शुरू कर दिया हो और आपके बिना टर्न पूरा कर लिया हो। उपयोग /api/ai/chat/abort जानबूझकर एक मोड़ रोकना, और /api/ai/chat/queue सत्र व्यस्त होने पर एक संदेश जोड़ने के लिए।
प्रदाता के बिना स्ट्रीम कैसी दिखती है
कोई एआई प्रदाता कॉन्फ़िगर नहीं होने के कारण, स्ट्रीम अभी भी खुलती है और एक टाइप की गई त्रुटि के साथ उत्तर देती है, जिसके बाद दिल की धड़कन होती है। एक ताज़ा साइडकार से लिया गया:
data: {"type":"error","sessionId":"","code":"config","message":"No AI provider is configured. Add an API key in the AI settings."}
data: {"type":"heartbeat"} - HTTP स्थिति अभी भी 200 और सामग्री प्रकार है
text/event-stream: कॉन्फ़िगरेशन समस्याएं डोमेन परिणाम हैं, जिन्हें ईवेंट के रूप में वितरित किया जाता है। sessionIdखाली है क्योंकि कोई सत्र नहीं बनाया गया।heartbeatफ़्रेम कनेक्शन को जीवित रखते हैं; प्रतिपादन में उनकी उपेक्षा करें और उन्हें प्रगति के रूप में न गिनें।- प्रत्येक फ़्रेम एक रिक्त रेखा के साथ समाप्त होता है। रिक्त रेखाओं को विभाजित करके और जोड़कर पार्स करें
data:एक फ़्रेम की पंक्तियाँ, जैसा कि SDK इटरेटर करता है।
बिना किसी मॉडल के अपने क्लाइंट का परीक्षण करें
किसी ग्राहक को क्रेडेंशियल्स के बिना साइडकार पर इंगित करें: यह बिना किसी लागत के पूर्ण एसएसई पथ और त्रुटि शाखा का अभ्यास करता है।