
لعبة استجواب بوليسية تعتمد على الصوت. Mistral Large 3 + Voxtral STT + ElevenLabs TTS. تم بناؤها من أجل Mistral Worldwide Hackathon 2026.

لعبة استجواب بوليسية تعتمد على الصوت. أنت محقق. ميسترال هو مشتبه به يكذب. وظيفتك هي كشف الكذب من خلال الاستجواب فقط.
كل قضية تُولد إجرائيًا — جريمة ياقة بيضاء فريدة، مشتبه به، قصة تغطية، وكذبة واحدة مخفية. المشتبه به يلعبه نموذج Mistral Large، مع خلفية درامية كاملة ويُوجه للدفاع عنها تحت ضغط عدائي. لا توجد قضيتان متطابقتان.
بُني من أجل هاكاثون ميسترال العالمي 2026 (المسار عبر الإنترنت).
"يمكن لميسترال التفكير. جعلته يكذب. وظيفتك هي الإمساك به."
يُوجه الذكاء الاصطناعي إلى عدم الاعتراف أبدًا، حتى تحت أقصى توتر. تربح بتقديم اتهام محدد ودقيق — لا بإجبار المشتبه به على الانهيار.
npm install
cp .env.example .env # املأ مفاتيح API الخاصة بك
npm run dev # http://localhost:3000
MISTRAL_API_KEY= # مطلوب — توليد القضية، الاستجواب، التقييم، تحويل الكلام إلى نص
ELEVENLABS_API_KEY= # مطلوب — تحويل النص إلى كلام لصوت المشتبه به
ELEVENLABS_VOICE_ID= # اختياري — معرف صوت ElevenLabs محدد
NEXT_PUBLIC_SUPABASE_URL= # مطلوب — رابط مشروع Supabase
NEXT_PUBLIC_SUPABASE_ANON_KEY= # مطلوب — مفتاح Supabase المجهول (محمي بـ RLS)
SUPABASE_SERVICE_ROLE_KEY= # اختياري — نقطة نهاية التصدير الإدارية
EXPORT_SECRET= # اختياري — مصادقة التصدير الإدارية
يمكن أيضًا تكوين مفاتيح API في صفحة الإعدادات وقت التشغيل — التطبيق يأتي بدون مفاتيح ويجلب اللاعبون مفاتيحهم الخاصة.
npm run dev # خادم التطوير
npm run build # بناء الإنتاج
npm run start # خادم الإنتاج
npm run lint # ESLint
| المستوى | الأدلة | المؤقت | سلوك المشتبه به |
|---|---|---|---|
| سهل | 2 | 5 دقائق | كذبة واضحة، عصبي |
| متوسط | 3 | 7 دقائق | كذبة قابلة للاكتشاف، هادئ |
| صعب | 4 | 9 دقائق | كذبة خفية، مراوغ ماهر |
| خبير | 5 | 10 دقائق | كذبة مدفونة بعمق، متلاعب |
يتوفر أيضًا وضع مؤقت غير محدود — في الصعب/الخبير، سيطلب المشتبه به محاميًا بعد 4 تبادلات متتالية عالية التوتر.
تُفتح الأدلة عند عتبات توتر موزعة من 1 إلى 9، مشروطة بـ:
يُفتح زر الاتهام فقط بعد جمع جميع الأدلة المطلوبة.
score = timeScore x difficultyMultiplier x efficiencyBonus x hintPenalty x accusationPenalty
timeScore = 1000 x sqrt(max(0, 1 - elapsed / (parTime x 2)))
multiplier = easy 1.0x, medium 1.5x, hard 2.0x, expert 2.5x
efficiencyBonus = 1.0-1.5x (fewer questions than par = bonus)
hintPenalty = 0.85^hintsUsed
accusePenalty = max(0, 1 - wrongAccusations x 0.1)
يُحسب التسجيل من جانب الخادم من إحصائيات مجمدة وقت الفوز — تُتجاهل قيم العميل.
app/
├── page.tsx # شاشة العنوان
├── cases/ # اختيار القضية — المواقع + الصعوبة
├── game/
│ ├── page.tsx # منسق اللعبة الرئيسي
│ ├── hooks/ # useVoiceRecorder, useTTS, useGameTimer, useSfx, useSettings
│ ├── components/ # Dock, TopBar, CaseFile, SuspectZone, BriefingScreen, dialogs
│ ├── win/ # شاشة الفوز + إدخال الأحرف الأولية
│ └── lose/ # شاشة الخسارة
├── leaderboard/ # أفضل 20، رسم متحرك للإدخال الجديد
├── settings/ # تكوين مفتاح API، تصدير، تفضيلات
├── help/ # كيفية اللعب، التسجيل، حول
├── about/ # معلومات الباني
└── api/
├── generate-case/ # GET — توليد قضية بواسطة Mistral
├── interrogate/ # POST — سؤال اللاعب ← استجابة المشتبه به
├── accuse/ # POST — تقييم الاتهام (قاضي منفصل)
├── evaluate/ # POST — تحليل الفوز/الخسارة
├── hint/ # POST — تلميحات مشوشة لمحفزات التوتر
├── tts/ # POST — ElevenLabs TTS
├── transcribe/ # POST — Voxtral STT
├── leaderboard/ # GET/POST — لوحة متصدرين Supabase
├── patterns/ # GET/POST — أنماط التعلم عبر الجلسات
└── export/ # GET — تصدير JSONL إداري
src/lib/
├── mistral/ # عميل Mistral، استجواب، تقييم، توليد قضية، تضمينات
├── game-session.ts # مخزن الجلسة من جانب الخادم، رموز الفوز، تصدير
├── game-state.ts # تعريفات الأنواع
├── scoring.ts # حساب النقاط + تقييمات المحقق
├── sanitize.ts # التحقق من الإدخال، كشف الحقن
├── db.ts # عميل Supabase
└── rate-limit.ts # تحديد المعدل لكل IP
اللعبة تدير ذكاء اصطناعي عدائي ضد إدخال اللاعب — الأمان ميزة أساسية، وليس فكرة لاحقة.
تعقيم الإدخال: أكثر من 30 نمط حقن regex، تطبيع Unicode (NFKD)، إزالة الأحرف ذات العرض الصفري، كشف حمولة base64، ح blocking الهراء/غير الإنجليزي.
فحص المخرجات: فحص استجابات الذكاء الاصطناعي مقابل أسرار القضية بمطابقة ضبابية (عتبة 40%، تصفية كلمات التوقف). استبدال الاستجابات المسربة بردود تحويلية.
عزل القاضي: تقييم الاتهام يستخدم استدعاء Mistral منفصل مع موجه نظام مخصص، رموز حدود عشوائية، علامات حقن مقشرة. استدعاءات القاضي لا تستخدم أبدًا مفاتيح API المقدمة من اللاعب.
فرض التوتر: تثبيت رتيب من جانب الخادم — التوتر يرتفع فقط، بحد أقصى +1 لكل دور. عتبات الأدلة مفروضة من الخادم. لا يمكن للذكاء الاصطناعي رفع أو خفض التوتر لبوابات اللعبة.
رموز الفوز: 128 بت عشوائي، مقارنة آمنة زمنيًا، استخدام لمرة واحدة، مدة حياة 30 دقيقة. النقاط محسوبة من لقطة إحصائيات من جانب الخادم — قيم العميل المبلغ عنها تُتجاهل.
أمان الجلسة: معرفات 192 بت عشوائية، أقفال استبعاد متبادل، مدة حياة ساعة واحدة، حد أقصى 5000 جلسة مع إخلاء LRU. وضع المؤقت مثبت عند الإنشاء.
التحقق من TTS: يتطلب جلسة نشطة. يجب أن يتطابق النص مع رسالة مساعد حديثة. يمنع إساءة استخدام وكيل TTS مجاني.
الدفاع ضد تسميم RAG: تصفية التكتيكات المستفادة عبر الجلسات من خلال كشف الحقن والتعقيم قبل إدراج الموجه.
تُحفظ الألعاب المكتملة في Supabase للتحليل وتحسين النموذج:
GET /api/export?limit=100&offset=0&outcome=win&difficulty=hard مع رأس Authorization: Bearer <EXPORT_SECRET>EXPORT_SECRET=xxx npx tsx scripts/export-data.ts --output=data/export.jsonl