- الرئيسية
- Documentation
- الجلسات
- سياسة إعادة المحاولة التلقائية لغير الضغط
سياسة إعادة المحاولة التلقائية لغير الضغط
يصف هذا المستند مسار إعادة المحاولة القياسي لأخطاء API في AgentSession.
يستثني هذا المستند صراحةً استرداد تجاوز السياق عبر الضغط التلقائي. تتولى منطق الضغط معالجة التجاوز، وهو موثق بشكل منفصل في compaction.md.
ملفات التنفيذ
Section titled “ملفات التنفيذ”../src/session/agent-session.ts../src/config/settings-schema.ts../src/modes/controllers/event-controller.ts../src/modes/rpc/rpc-mode.ts../src/modes/rpc/rpc-client.ts../src/modes/rpc/rpc-types.ts
حدود النطاق مقابل الضغط
Section titled “حدود النطاق مقابل الضغط”يتم التحقق من إعادة المحاولة والضغط من مسار agent_end نفسه، غير أنهما مفصولان عن قصد:
- يفحص
agent_endآخر رسالة من المساعد. - يعمل
#isRetryableError(...)أولاً. - إذا بدأت إعادة المحاولة، يُتخطى التحقق من الضغط في تلك الدورة.
- تُستثنى أخطاء تجاوز السياق استثناءً صارماً من تصنيف إعادة المحاولة (يختصر
isContextOverflow(...)إعادة المحاولة). - يمر التجاوز بعدها إلى
#checkCompaction(...)بدلاً من إعادة المحاولة القياسية.
إذن: تستخدم حالات الفشل من نوع الحمل الزائد/معدل الطلبات/الخادم/الشبكة سياسة إعادة المحاولة هذه؛ أما تجاوز نافذة السياق فيستخدم استرداد الضغط.
تصنيف إعادة المحاولة
Section titled “تصنيف إعادة المحاولة”يتطلب #isRetryableError(...) استيفاء جميع الشروط التالية:
- يكون
stopReason === "error"للمساعد - وجود
errorMessage - ألا تكون الرسالة تجاوزاً للسياق
- مطابقة
errorMessageلـ#isRetryableErrorMessage(...)
مجموعة الأنماط القابلة لإعادة المحاولة الحالية (قائمة على التعبيرات النمطية):
- overloaded
- rate limit / usage limit / too many requests
- فئات الخوادم المشابهة لـ HTTP: 429، 500، 502، 503، 504
- service unavailable / server error / internal error
- connection error / fetch failed
- صياغة
retry delay
هذا تصنيف بمطابقة الأنماط النصية، وليس رموز أخطاء الموفر المكتوبة.
دورة حياة إعادة المحاولة وانتقالات الحالة
Section titled “دورة حياة إعادة المحاولة وانتقالات الحالة”حالة الجلسة المستخدمة في إعادة المحاولة:
#retryAttempt: number(0تعني الخمول)#retryPromise: Promise<void> | undefined(يتتبع دورة حياة إعادة المحاولة الجارية)#retryResolve: (() => void) | undefined(يحل#retryPromise)#retryAbortController: AbortController | undefined(يلغي سكون التراجع)
التدفق (#handleRetryableError):
- قراءة مجموعة إعدادات
retry. - إذا كان
retry.enabled === false، توقف فوراً (false، لم تبدأ إعادة المحاولة). - زيادة
#retryAttempt. - إنشاء
#retryPromiseمرة واحدة (أول محاولة في السلسلة). - إذا تجاوزت المحاولة
retry.maxRetries، إصدار حدث الفشل النهائي والتوقف. - حساب التأخير:
retry.baseDelayMs * 2^(attempt-1). - لأخطاء حد الاستخدام، تحليل تلميحات إعادة المحاولة واستدعاء تخزين المصادقة (
markUsageLimitReached(...)؛ إذا نجح تبديل الموفر/النموذج، يُجبر التأخير على0. - إصدار
auto_retry_start. - إزالة رسالة خطأ المساعد الأخيرة من حالة وقت تشغيل العامل (تُحتفظ بها في سجل الجلسة الدائم).
- النوم مع دعم الإلغاء.
- عند الاستيقاظ، جدولة
agent.continue()عبرsetTimeout(..., 0).
ما يُعيد تهيئة عدادات إعادة المحاولة
Section titled “ما يُعيد تهيئة عدادات إعادة المحاولة”يُعاد تعيين #retryAttempt إلى 0 في هذه الحالات:
- أول رسالة مساعد ناجحة غير خاطئة وغير ملغاة بعد بدء إعادة المحاولة (تُصدر
auto_retry_end { success: true }) - إلغاء إعادة المحاولة أثناء نوم التراجع
- مسار تجاوز الحد الأقصى لإعادة المحاولة
يحل #retryPromise ويصفى عند انتهاء سلسلة إعادة المحاولة (نجاح أو إلغاء أو تجاوز الحد الأقصى)، عبر #resolveRetry().
التراجع ودلالات الحد الأقصى للمحاولات
Section titled “التراجع ودلالات الحد الأقصى للمحاولات”الإعدادات:
retry.enabled(الافتراضيtrue)retry.maxRetries(الافتراضي3)retry.baseDelayMs(الافتراضي2000)
ترقيم المحاولات:
- يُزاد عداد المحاولات قبل التحقق من الحد الأقصى
- تستخدم أحداث البدء المحاولة الحالية (بترقيم يبدأ من 1)
- يُبلّغ حدث انتهاء تجاوز الحد الأقصى بـ
attempt: this.#retryAttempt - 1(عدد آخر محاولة إعادة)
تسلسل التراجع مع الإعدادات الافتراضية:
- المحاولة 1: 2000 مللي ثانية
- المحاولة 2: 4000 مللي ثانية
- المحاولة 3: 8000 مللي ثانية
تُستخدم مدخلات تجاوز التأخير فقط في مسار معالجة حد الاستخدام، وفقط للتأثير في قرار تبديل النموذج/الحساب في تخزين المصادقة. في مسار إعادة المحاولة الرئيسي غير المضغوط، يظل التراجع تأخيراً أسياً محلياً ما لم ينجح التبديل (delayMs = 0).
آليات الإلغاء
Section titled “آليات الإلغاء”الإلغاء الصريح لإعادة المحاولة
Section titled “الإلغاء الصريح لإعادة المحاولة”abortRetry():
- يلغي
#retryAbortController(إن وُجد) - يحل وعد إعادة المحاولة (
#resolveRetry()) لإلغاء حظر المنتظرين
إذا أصاب الإلغاء أثناء النوم، يُصدر مسار الالتقاط:
auto_retry_end { success: false, finalError: "Retry cancelled" }- يُعيد تعيين المحاولة/وحدة التحكم
تفاعل الإلغاء العام للعملية
Section titled “تفاعل الإلغاء العام للعملية”يستدعي abort() الدالة abortRetry() قبل إلغاء تدفق العامل النشط. يضمن ذلك إلغاء تراجع إعادة المحاولة عند إصدار المستخدم أمر إلغاء عام.
تفاعل واجهة المستخدم النصية (TUI)
Section titled “تفاعل واجهة المستخدم النصية (TUI)”عند auto_retry_start، تقوم EventController بـ:
- تبديل معالج
Escإلىsession.abortRetry() - عرض نص المحمّل:
Retrying (attempt/maxAttempts) in Ns… (esc to cancel)
عند auto_retry_end، تستعيد معالج Esc السابق وتمسح حالة المحمّل.
سلوك البث واكتمال الطلب
Section titled “سلوك البث واكتمال الطلب”يتوقف prompt() في نهاية المطاف على #waitForRetry() بعد عودة agent.prompt(...).
التأثير:
- لا يُحسم استدعاء الطلب بالكامل حتى تنتهي أي سلسلة إعادة محاولة مبدوءة (نجاح/فشل/إلغاء)
- دورة حياة إعادة المحاولة جزء من حدود تنفيذ طلب منطقي واحد
يمنع ذلك المستدعين من معاملة دورة التكرار قيد إعادة المحاولة على أنها مكتملة مبكراً.
الضوابط: الإعدادات وRPC
Section titled “الضوابط: الإعدادات وRPC”مفاتيح التهيئة
Section titled “مفاتيح التهيئة”محددة في مخطط الإعدادات ضمن مجموعة retry:
retry.enabledretry.maxRetriesretry.baseDelayMs
مبدّلات برمجية في الجلسة:
setAutoRetryEnabled(enabled)تكتبretry.enabledautoRetryEnabledتقرأretry.enabledisRetryingتُبلّغ عما إذا كانت وعد دورة حياة إعادة المحاولة نشطة
ضوابط RPC
Section titled “ضوابط RPC”سطح أوامر RPC:
set_auto_retry→session.setAutoRetryEnabled(command.enabled)abort_retry→session.abortRetry()
مساعدات العميل:
RpcClient.setAutoRetry(enabled)RpcClient.abortRetry()
يُعيد كلا الأمرين استجابات النجاح؛ تأتي تفاصيل تقدم/فشل إعادة المحاولة من أحداث الجلسة المبثوثة، لا من حمولات استجابة الأوامر.
إصدار الأحداث وإظهار الفشل
Section titled “إصدار الأحداث وإظهار الفشل”أحداث إعادة المحاولة على مستوى الجلسة:
auto_retry_start { attempt, maxAttempts, delayMs, errorMessage }auto_retry_end { success, attempt, finalError? }
الانتشار:
- تُصدر عبر
AgentSession.subscribe(...) - تُمرَّر إلى مشغّل الامتداد كأحداث امتداد
- في وضع RPC، تُمرَّر مباشرةً ككائنات أحداث JSON (
session.subscribe(event => output(event))) - في واجهة المستخدم النصية، تستهلكها
EventControllerلواجهة المحمّل/الخطأ
إظهار الفشل النهائي:
- عند تجاوز الحد الأقصى أو الإلغاء،
auto_retry_end.success === false - تعرض واجهة المستخدم النصية:
Retry failed after N attempts: <finalError> - تستقبل الامتدادات/الخطافات
auto_retry_endبالحقول ذاتها - يستقبل مستهلكو RPC كائن الحدث ذاته في تدفق stdout
شروط التوقف الدائم
Section titled “شروط التوقف الدائم”تتوقف إعادة المحاولة ولن تستمر تلقائياً عند حدوث أي مما يلي:
retry.enabledخاطئ- الخطأ غير مصنف كقابل لإعادة المحاولة
- الخطأ تجاوز للسياق (مفوض إلى مسار الضغط)
- تجاوز الحد الأقصى لإعادة المحاولة
- إلغاء المستخدم لإعادة المحاولة (
abort_retryأوEscأثناء محمّل إعادة المحاولة) - يلغي الإلغاء العام (
abort) إعادة المحاولة أولاً
لا يزال بإمكان سلسلة إعادة محاولة جديدة البدء لاحقاً عند حدوث خطأ قابل لإعادة المحاولة في المستقبل بعد إعادة تعيين العدادات.
تحفظات التشغيل
Section titled “تحفظات التشغيل”- التصنيف مطابقة نصية بتعبيرات نمطية؛ لا تُستخدم هنا أخطاء الموفر الهيكلية الخاصة بكل مزوّد.
- تحذف إعادة المحاولة رسالة خطأ المساعد الفاشلة من سياق وقت التشغيل قبل الاستمرار، لكن سجل الجلسة لا يزال يحتفظ بإدخال الخطأ ذاك.
- يكشف
RpcSessionStateحالياً عنautoCompactionEnabledلكن لا يكشف عن حقلautoRetryEnabled؛ يجب على مستدعي RPC تتبع حالة مبدّلهم الخاصة أو الاستعلام عن الإعدادات عبر واجهات API أخرى.