new-term-radar
Daily radar for new AI terms: names of new models, products and repos, caught on X, Hugging Face, GitHub and sitemaps before keyword tools list them.
حاضر يرد على عملاء متجرك في واتساب وماسنجر وانستقرام بمعرفة بزنسك أنت: الأسعار، المخزون، السياسات. بلا اختراع، وبتحويل ذكي لموظف عند الحاجة.
Translation pending
MarketingTypeScript · DartGitHub @AL-atharbehOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗منصة SaaS تعطي كل بزنس (محل ذهب، محل ملابس، مطعم، صيدلية…) وكيل ذكاء اصطناعي خاص فيه يرد على عملائه عبر الواتساب وماسنجر وانستقرام، يفهم بزنسه تحديداً، ويحوّل لموظف بشري عند الحاجة.
محرك واحد، بيانات معزولة تماماً لكل عميل.
المشكلة اللي صمّم عليها هذا النظام: كيف يخدم نفس الكود مئة بزنس مختلف، بدون أي احتمال أن يرد وكيل محل الملابس بمعلومة من المطعم؟
الجواب على ثلاث طبقات:
┌─────────────────────────────────────────────────────────────┐
│ الطبقة ١ — قاعدة البيانات │
│ كل جدول يحمل tenantId، وكل مفتاح فريد مركّب معه: │
│ @@unique([tenantId, sku]) @@unique([channel, externalId]) │
│ ⇒ رقم واتساب واحد لا يمكن أن يعود لعميلين. │
├─────────────────────────────────────────────────────────────┤
│ الطبقة ٢ — طبقة النطاق (src/lib/tenancy.ts) │
│ لا شيء في المشروع يلمس prisma مباشرة لقراءة بيانات بزنس. │
│ كل شيء يمر عبر tenantScope(tenantId) التي تحقن الـ tenantId │
│ داخل كل where. ما في دالة تستقبل tenantId كوسيط قابل للتلاعب. │
├─────────────────────────────────────────────────────────────┤
│ الطبقة ٣ — أدوات الوكيل (src/lib/agent/tools.ts) │
│ الأدوات مبنية داخل closure على scope عميل واحد. النموذج │
│ لا يمرر tenantId إطلاقاً — غير موجود في مخطط أي أداة. │
│ ⇒ حتى لو "هلوس" النموذج، ما في مسار برمجي ينفّذ التسريب. │
└─────────────────────────────────────────────────────────────┘
النقطة الجوهرية: العزل ليس اتفاقاً نلتزم به، بل خاصية بنيوية. لكي يتسرّب شيء،
يجب تعديل tenancy.ts نفسه — لا يكفي خطأ في مكان آخر.
عميل يكتب على واتساب
│
▼
POST /api/webhooks/meta/<tenantSlug> ← رابط منفصل لكل عميل
│
├─ تحقق من توقيع Meta (HMAC-SHA256) بسرّ ذلك العميل
├─ parseWebhook() → InboundMessage موحّدة (واتساب/ماسنجر/انستقرام)
└─ رد 200 فوراً، والمعالجة تكمل بـ after() ← Meta تعيد الإرسال بعد 20ث
│
▼
handleInbound() (src/lib/pipeline.ts)
│
├─ ① حلّ العميل من phone_number_id → رفض إن كان مجهولاً
├─ ② حالة الاشتراك ACTIVE؟
├─ ③ قفل لكل محادثة ← ثلاث رسائل سريعة تُعالَج بالترتيب لا بالتسابق
├─ ④ رسالة مكرّرة؟ (Meta تعيد الإرسال) → تجاهل
├─ ⑤ المحادثة محوّلة لموظف بشري؟ → الوكيل يصمت تماماً
├─ ⑥ مرفق غير نصي؟ → رد جاهز
├─ ⑦ كلمة تفرض التحويل ("شكوى")؟ → تحويل قبل صرف أي توكن
├─ ⑧ تجاوز السقف اليومي؟ → تحويل + تنبيه
│
▼
runAgentTurn() (src/lib/agent/engine.ts)
│
├─ system prompt مبني من صفّ هذا العميل فقط [مكاش]
├─ آخر ٢٠ رسالة من هذه المحادثة فقط
├─ ٤ أدوات مربوطة بنطاق هذا العميل
└─ Claude tool runner (حتى ٦ جولات)
│
▼
حفظ الرد + الأدوات المستدعاة + استهلاك التوكنات
│
▼
إرسال عبر Meta Graph API
الفرق ليس في الكود، بل في ما يُحقن للنموذج وقت التشغيل. وهذا يأتي من مصدرين مقسومين بقاعدة واضحة:
| نوع المعرفة | أين توضع | لماذا |
|---|---|---|
| هوية البزنس، الدوام، العنوان، سياسة التوصيل والاسترجاع، الأسئلة الشائعة | داخل system prompt | صغيرة وثابتة ⇒ تُكاش وتُقرأ بـ ~١٠٪ من سعر الإدخال |
| الكتالوج (قد يكون ٥٠٠ منتج) | أداة search_catalog | كبير جداً على السياق، ويتغيّر يومياً |
| الأرقام المتغيّرة (سعر الذهب) | أداة get_live_data | يجب ألا تُخزَّن في نص ثابت أبداً |
مثال عملي على نفس الكود:
محل ذهب — العميل: «كم سعر الذهب اليوم؟»
→ الوكيل يستدعي get_live_data("gold_price") → يرجع {karat_21: 54.7, ...} مع طابع زمني
→ إذا كانت القيمة أقدم من ١٢ ساعة، ترجع الأداة أمراً صريحاً بعدم ذكر الرقم
والتحويل لموظف. هذا يمنع أخطر خطأ ممكن في محل ذهب: تسعيرة خاطئة.
محل ملابس — العميلة: «كم سعر الفستان الأزرق مقاس M؟»
→ search_catalog("فستان ازرق") → يرجع السعر والمقاسات والتوفر
→ لو المقاس غير متوفر، customPolicy الخاص بهذا المحل يوجّهه لاقتراح البدائل.
مطعم — نفس المحرك، كتالوج مختلف، ولا يوجد مصدر بيانات حيّة أصلاً.
هذه أهم ما يفصل منتجاً قابلاً للبيع عن تجربة تقنية:
maxRepliesPerDay) — حماية من الفاتورة المفاجئة والاستنزاف.النموذج الافتراضي claude-opus-5 مع effort: "low" (خدمة العملاء مسار قصير
حساس للزمن، فالجهد المنخفض يعطي نفس الجودة بتكلفة وزمن أقل بكثير).
الرافعة الأهم هي كاش تعليمات النظام: نص البزنس ثابت عبر آلاف الرسائل، فيُقرأ من الكاش بدل إعادة احتسابه. لهذا وُضع الوقت المتغيّر في كتلة منفصلة بعد نقطة الكاش — أي بايت يتغيّر قبلها يبطلها بالكامل.
كلا الأمرين قابل للضبط لكل عميل من Tenant.modelId و Tenant.effort —
عميل بحجم كبير قد يستحق claude-sonnet-5 وعميل بمنتجات معقّدة قد يستحق effort: "medium".
راقب usage.cache_read_input_tokens في جدول Message: إن بقي صفراً، هناك ما يبطل الكاش.
src/
├── app/
│ ├── api/
│ │ ├── webhooks/meta/[tenantSlug]/route.ts استقبال Meta + التحقق من التوقيع
│ │ └── chat/route.ts ساحة التجربة
│ ├── admin/ لوحة التحكم الكاملة
│ │ ├── actions.ts كل عمليات الحفظ (server actions)
│ │ └── [slug]/ إعدادات · منتجات · أسئلة ·
│ │ بيانات حيّة · قنوات · محادثات · عملاء
│ └── playground/[slug]/ واجهة تجربة الوكيل
└── lib/
├── tenancy.ts ★ طبقة العزل — نقطة الدخول الوحيدة للبيانات
├── pipeline.ts ★ خط المعالجة والبوابات الدفاعية
├── agent/
│ ├── engine.ts يختار المزوّد ويجمع النتيجة
│ ├── prompt.ts بناء الشخصية من صفّ العميل
│ ├── tools.ts ٤ أدوات محايدة مربوطة بنطاق عميل واحد
│ └── providers/
│ ├── anthropic.ts Claude — الإنتاج (كاش + tool runner)
│ └── groq.ts Groq — تجربة مجانية (حلقة أدوات يدوية)
├── channels/
│ ├── types.ts InboundMessage الموحّدة
│ └── meta.ts توقيع، تطبيع، إرسال
├── auth.ts جلسة موقّعة بـ HMAC (Web Crypto — تعمل على Edge)
├── crypto.ts AES-256-GCM لمفاتيح القنوات
├── arabic.ts تطبيع عربي للبحث ("ازرق" = "أزرق")
└── db.ts
# ١) املأ .env (DATABASE_URL و DIRECT_URL من Supabase، و ANTHROPIC_API_KEY)
cp .env.example .env
# ٢) مفتاح التشفير
echo "ENCRYPTION_KEY=\"$(openssl rand -hex 32)\"" >> .env
# ٣) أنشئ الجداول
npm run db:push
# ٤) ٣ عملاء تجريبيين: ذهب، ملابس، مطعم
npm run seed
# ٥) اختبر العزل (بدون أي نداء للنموذج)
npm run verify
# ٦) عرض حيّ لبزنسين مختلفين
npx tsx --env-file=.env scripts/demo.ts
# ٧) محادثة تفاعلية
npm run chat dhahab
# أو من المتصفح
npm run dev → http://localhost:3000
AGENT_PROVIDER في .env:
| القيمة | متى |
|---|---|
anthropic | الإنتاج — عربية ممتازة + كاش يخفّض التكلفة ٩٠٪ |
groq | التجربة المجانية — يثبت أن السباكة والأدوات والعزل تعمل |
منطق العزل والحواجز مشترك بين الاثنين ولا يتغيّر بتغيّر المزوّد.
لمعرفة النماذج المتاحة على حساب Groq: npx tsx --env-file=.env scripts/groq-models.ts
المتغيّرات المطلوبة على منصة النشر (Vercel أو غيرها):
DATABASE_URL · DIRECT_URL · ENCRYPTION_KEY · ADMIN_PASSWORD ·
APP_BASE_URL · AGENT_PROVIDER مع مفتاح المزوّد المختار.
بعد إضافتها أعد النشر — لا تُطبَّق على نشر قديم. ثم افتح /api/health
للتأكد: يبلّغ عن أي متغيّر ناقص وحالة الاتصال بقاعدة البيانات بدون كشف أي قيمة.
بدون ADMIN_PASSWORD تُغلق اللوحة بالكامل — اختيار متعمّد: الفشل نحو الإغلاق
لا نحو الانفتاح.
يجب استخدام WhatsApp Business Platform (Meta Cloud API) الرسمي — وليس رقماً عادياً عبر أدوات غير رسمية، وإلا تعرّض الرقم للحظر.
ChannelAccount: channel=WHATSAPP, externalId=<phone_number_id>,
accessTokenEnc=encrypt(token), verifyToken=<نص تختاره>https://<نطاقك>/api/webhooks/meta/<tenantSlug> مع نفس الـ verify tokenmessagesماسنجر وانستقرام: نفس الويبهوك، تتغيّر externalId إلى Page ID / IG Account ID.
ما بُني هنا يخدم عشرات العملاء على خادم واحد. عند التوسّع:
| الحد | المسار |
|---|---|
القفل في الذاكرة (pipeline.ts) | قفل Redis عند تشغيل أكثر من نسخة |
المعالجة بـ after() | طابور BullMQ مع إعادة محاولة |
البحث بـ ILIKE | Postgres full-text أو pgvector عند تجاوز آلاف المنتجات |
| المعرفة في system prompt | RAG عند تجاوز الأسئلة الشائعة ~٥٠ سؤالاً |
| كلمة سر واحدة للوحة | حسابات وصلاحيات عند إعطاء العملاء وصولاً للوحاتهم |
| نص فقط | استقبال الصور (فحص قطعة ذهب من صورة) واقعي جداً كميزة قادمة |