عدم التكرار
الشبكات تتعطل. قد ينتهي وقت الطلب بعد أن ينجز الخادم العمل فعلًا، فتنشئ إعادة المحاولة العادية جلسة ثانية أو رسالة ثانية أو إجابة ثانية. يمنحك K-Agent أداتين لجعل إعادة المحاولة آمنة.
Idempotency-Key
رابط القسم «Idempotency-Key»أرسل مفتاحًا فريدًا مع أي طلب POST أو DELETE. وإذا أعدت المحاولة بالمفتاح نفسه تحصل على النتيجة المحفوظة بدل تنفيذ ثانٍ:
curl https://api.k-agent.kerneltics.com/v1/sessions \ -H "Authorization: Bearer $KAGENT_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 6f1c2a0e-8d3b-4c55-9a77-1e2f3d4c5b6a" \ -d '{"agent": "store-assistant", "external_id": "order-8812", "input": "وين طلبي؟"}'const key = crypto.randomUUID(); // create once, reuse for every retry of this requestconst RETRY_409 = new Set(['idempotency_in_progress', 'session_busy', 'session_queue_full']);
async function createSessionWithRetry(body, attempts = 4) { for (let i = 0; i < attempts; i++) { try { const res = await fetch('https://api.k-agent.kerneltics.com/v1/sessions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.KAGENT_API_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': key, }, body: JSON.stringify(body), }); if (res.status === 409) { const { error } = await res.clone().json(); if (!RETRY_409.has(error.code)) return res; } else if (res.status < 500 && res.status !== 429) { return res; } } catch { // network error: retry with the same key } await new Promise((r) => setTimeout(r, 500 * 2 ** i)); } throw new Error('Gave up after retries');}import os, time, uuid, requests
key = str(uuid.uuid4()) # create once, reuse for every retry of this requestRETRY_409 = {"idempotency_in_progress", "session_busy", "session_queue_full"}
def create_session_with_retry(body: dict, attempts: int = 4) -> requests.Response: for i in range(attempts): try: r = requests.post( "https://api.k-agent.kerneltics.com/v1/sessions", headers={"Authorization": f"Bearer {os.environ['KAGENT_API_KEY']}", "Idempotency-Key": key}, json=body, timeout=120, ) if r.status_code == 409: if r.json()["error"]["code"] not in RETRY_409: return r elif r.status_code < 500 and r.status_code != 429: return r except requests.ConnectionError: pass # network error: retry with the same key time.sleep(0.5 * 2 ** i) raise RuntimeError("Gave up after retries")القواعد
رابط القسم «القواعد»- النطاق. المفتاح محصور في مشروعك، وبيانات الاعتماد التي أرسلته، والمسار (الطريقة ونمط المسار). والمفتاح نفسه على مسار آخر مفتاح مختلف.
- الطول. من 1 إلى 255 حرفًا (وإلا
400 invalid_idempotency_key). ومعرّف UUID v4 مثالي. - مدة الحفظ. تُحفظ النتائج 24 ساعة. وبعدها يمكن استخدام المفتاح من جديد.
- الإعادة ترجع الحالة والجسم الأصليين، مع الترويسة
Idempotent-Replayed: true. - المفتاح نفسه مع طلب مختلف — جسم آخر أو معرّف آخر في المسار — يعيد
422 idempotency_key_reused. وتعتمد المقارنة على الجلسة بعد تحديدها، فمخاطبتها بمعرّفsess_…أو بـexternal_idتُعدّ الطلب نفسه. - ما زال قيد التنفيذ. إذا لم ينتهِ الطلب الأول تعيد إعادة المحاولة
409 idempotency_in_progress. انتظر وأعد المحاولة بالمفتاح نفسه. - أخطاء الخادم لا تُحفظ. خطأ
5xxيقع قبل بدء أي عمل يمكن إعادته بالمفتاح نفسه وسيُنفَّذ من جديد.
الطلبات التي تبدأ تشغيلًا
رابط القسم «الطلبات التي تبدأ تشغيلًا»في ask، وPOST /v1/sessions مع input، والرسائل، وsubmit_tool_outputs، يرتبط المفتاح بالتشغيل فور وجوده:
- تعيد إعادة المحاولة الحالة الحالية للتشغيل بالشكل المعتاد لاستجابة نقطة النهاية — فإن كان قد انتهى منذ ذلك الحين تحصل على التشغيل المنتهي؛
- إعادة طلب بثّ تعيد ربطك ببث ذلك التشغيل من بدايته؛
- لا يكون
409 idempotency_in_progressممكنًا إلا في اللحظة القصيرة قبل وجود التشغيل.
الطلبات التي تعيد سرًا
رابط القسم «الطلبات التي تعيد سرًا»إنشاء مفتاح API أو استبداله، وإصدار رمز عميل، وبدء جلسة ودجت، وإنشاء نقطة استقبال ويب هوك أو تغيير سرها، وقراءة سر توقيع الأدوات — كلها تعيد سرًا مرة واحدة. وإعاداتها ترجع المورد نفسه مع السر بقيمة null و"secret_redacted": true — فالسر نفسه لا يُحفظ لإعادته أبدًا.
client_message_id
رابط القسم «client_message_id»لرسائل المحادثة آلية ثانية أبسط: أعطِ كل رسالة معرّفك الخاص.
curl https://api.k-agent.kerneltics.com/v1/sessions/order-8812/messages \ -H "Authorization: Bearer $KAGENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"input": "شكرًا!", "client_message_id": "wa-msg-77121"}'- المعرّف
client_message_idنفسه في الجلسة نفسها يعيد{session, message, run}الأصلية بالحالة200معIdempotent-Replayed: true— دون رسالة ثانية ودون إجابة ثانية. - المعرّف نفسه مع نص مختلف يعيد
409 client_message_id_conflict. - لا تنتهي صلاحيته ما دامت الجلسة موجودة، ما يجعله الأداة المناسبة للقنوات التي تعيد تسليم الرسائل بعد ساعات (الويب هوك من منصات المراسلة، وتطبيقات الجوال التي تعيد الإرسال بعد استعادة الاتصال).
استخدم الاثنين متى استطعت: client_message_id لمنع تكرار الرسالة نفسها، وIdempotency-Key لجعل طلب HTTP آمنًا عند إعادته.