kassette؛ ریتری ایجنتها بدون تکرار کارهای انجامشده
خلاصهٔ کاملتر
kassette یه کتابخانهی کوچیک و بدون وابستگی (zero-dependency) با TypeScript ـه که ادعاش اینه ورکفلوهای ایجنتی رو بادوام (durable) میکنه. ایدهش سادهست: مرحلههای تمامشده تو یه ژورنال ثبت میشن و موقع retry بعد از کرش، تایماوت یا ریدیپلوی، همونها replay میشن بهجای اینکه دوباره اجرا بشن.
نکتهی اصلی که تو معرفیش روش تأکید شده اینه: مسئله «چطور دوباره اجراش کنم؟» نیست، «چطور کاری که یه بار انجام شده رو دوباره انجام ندم؟» ـه. استک فعلی شما retry رو راحت میکنه ولی امن نمیکنه؛ چون یه ریتری ساده یعنی دوباره صدا زدن مدل و دوباره اجرا کردن ابزارها، با همهی هزینه و عوارض جانبیش.
چهار قابلیتی که برشمرده اینه: replay مرحلههای تمامشده و برگردوندن نتیجهی ضبطشده؛ suspend برای انتظار بدون اجرا، یعنی پروسه میتونه کاملاً خارج بشه و منتظر تأیید انسان، وبهوک یا جاب CI بمونه و بعد از رسیدن رویداد ادامه پیدا کنه؛ استفاده از سیستم retry موجود خودت، چون kassette یه کتابخونهست نه رانتایم؛ و نگهداری state تو یه ژورنال ساده.
همین ژورنال جالبترین بخش طراحیشه: هر اجرا یه فایل JSONL خوانا روی فایلسیستم یا object storage ـه که همزمان نقش state، مسیر ادامه (resume point) و audit trail رو بازی میکنه. رکوردهاش هم صریحن: start، step با نتیجهی هر مرحله، suspend با نام رویدادی که منتظرشه، resume با مقدار دریافتی، و complete.
از نظر کد، ورکفلو همون async معمولی میمونه و فقط مرحلههای مهم داخل ctx.step() پیچیده میشن؛ جایی هم که به تأیید انسان نیاز داری ctx.suspend() صدا زده میشه و پروسه میتونه همونجا تموم بشه و بعداً با agent.resume() از هرجایی ادامه پیدا کنه.
const agent = kassette(async (ctx, ticket) => {
const analysis = await ctx.step('analyze', () =>
llm.chat('Diagnose this issue and recommend a fix', { ticket })
);
const approval = await ctx.suspend('human-approval');
const result = await ctx.step('apply-fix', () => executeTool(analysis.suggestedAction));
return { outcome: 'resolved', result };
}, { storage: new LocalStorage('.kassette') });نمونههای آمادهای هم منتشر شده که کاربردها رو نشون میده: یه حلقهی سادهی think-act-observe که بعد از کرش از اولین مرحلهی ناتمام ادامه میده؛ یه سناریوی اعتبارسنجی وام با parallel() برای جمعآوری همزمان داده و گیت تأیید انسانی؛ یه دستیار دیپلوی مبتنی بر وبهوک با sleep()؛ و یه ایجنت کدنویسی که با fork() چند پیادهسازی رو امتحان میکنه و در صورت شکست به مرحلهی برنامهریزی برمیگرده.
دو نمونهی دیگه هم نشون میده چطور به استک موجود وصل میشه: یه میدلور برای ضبط فراخوانیهای LLM از طریق Vercel AI SDK (حتی پاسخهای استریمی) که موقع replay بدون تماس با ارائهدهنده جواب ضبطشده رو برمیگردونه، و یه نمونه روی Cloudflare Queue که تحویل مجدد صف نقش تشخیصدهندهی کرش رو بازی میکنه و یه isolate تازه از روی R2 ادامه میده.
نکات کلیدی:
- کتابخانهی TypeScript بدون وابستگی، نه یه رانتایم مستقل
- ژورنال JSONL همزمان state، نقطهی ادامه و audit trail ـه
- step() نتیجه رو ضبط میکنه، suspend() اجازه میده پروسه کامل خارج بشه
- صف یا job runner فعلی خودت با همون runId کار retry رو انجام میده
- ذخیرهسازی روی فایلسیستم یا object storage با تریدآفهای fencing و retention




