/**
 * src/agent/router.ts
 * موجه النوايا — يصنف الرسائل الواردة باستخدام NVIDIA NIM (Qwen 2.5)
 * Ultra-fast intent classification to route to the right model tier
 */
import { z } from 'zod';
import { createChildLogger } from '../utils/logger.js';
import { nvidia } from '../models/nvidia.js';
const log = createChildLogger('agent:router');
// ─── Intent Types ────────────────────────────────────────────────────
export const INTENTS = [
    'greeting',
    'product_inquiry',
    'pricing',
    'booking',
    'complaint',
    'voice_note',
    'image',
    'document',
    'complex_question',
    'follow_up',
    'off_topic',
    'escalate_to_human',
];
export const routerResultSchema = z.object({
    intent: z.enum(INTENTS),
    confidence: z.number().min(0).max(1),
    suggestedTier: z.enum(['flash', 'brain', 'reasoning']),
});
// ─── Tier Mapping ────────────────────────────────────────────────────
/** خريطة النوايا → المستوى المقترح */
const INTENT_TIER_MAP = {
    greeting: 'flash',
    follow_up: 'flash',
    off_topic: 'flash',
    product_inquiry: 'brain',
    pricing: 'brain',
    booking: 'brain',
    complaint: 'brain',
    voice_note: 'brain',
    image: 'brain',
    document: 'brain',
    complex_question: 'reasoning',
    escalate_to_human: 'flash',
};
// ─── Router ──────────────────────────────────────────────────────────
const ROUTER_SYSTEM_PROMPT = `أنت مصنف نوايا (intent classifier) فائق السرعة. مهمتك تحليل رسالة العميل وتصنيفها. أعد JSON فقط بدون أي نص آخر:
{
  "intent": "<one of: greeting, product_inquiry, pricing, booking, complaint, voice_note, image, document, complex_question, follow_up, off_topic, escalate_to_human>",
  "confidence": <0.0 to 1.0>
}

قواعد التصنيف:
- greeting: تحية أو سلام (مرحبا، هلا، السلام عليكم)
- product_inquiry: سؤال عن منتج أو خدمة
- pricing: سؤال عن سعر أو تكلفة
- booking: طلب حجز أو موعد
- complaint: شكوى أو مشكلة
- voice_note: إذا أُشير أن الرسالة ملاحظة صوتية
- image: إذا أُشير أن الرسالة تحتوي صورة
- document: إذا أُشير أن الرسالة تحتوي مستند
- complex_question: سؤال معقد يحتاج تفكير عميق أو مقارنة
- follow_up: متابعة لمحادثة سابقة
- off_topic: موضوع لا علاقة له بالعمل
- escalate_to_human: العميل يطلب التحدث مع شخص حقيقي

إذا الرسالة فيها "أبي أكلم شخص" أو "وكيل بشري" → escalate_to_human
إذا الرسالة قصيرة وغير واضحة → follow_up بثقة منخفضة`;
/**
 * تصنيف نية الرسالة الواردة
 * Uses NVIDIA NIM (Qwen 2.5) for fast, accurate classification
 */
export async function classifyIntent(messageText, context) {
    // تصنيف سريع بدون LLM لبعض الحالات الواضحة
    const quickResult = quickClassify(messageText, context);
    if (quickResult) {
        log.debug({ intent: quickResult.intent, method: 'quick' }, 'Quick classification');
        return quickResult;
    }
    // تصنيف عبر NVIDIA NIM (Qwen 2.5)
    try {
        let userMessage = messageText;
        if (context?.hasMedia) {
            userMessage = `[نوع الوسائط: ${context.mediaType ?? 'unknown'}] ${messageText}`;
        }
        if (context?.recentMessages?.length) {
            userMessage = `[آخر رسائل: ${context.recentMessages.slice(-3).join(' | ')}]\n\nالرسالة الحالية: ${userMessage}`;
        }
        const messages = [
            { role: 'system', content: ROUTER_SYSTEM_PROMPT },
            { role: 'user', content: userMessage },
        ];
        const response = await nvidia.chat(messages, {
            temperature: 0.1,
            maxTokens: 100,
            responseFormat: { type: 'json_object' },
        });
        // (Audit L3) Explicit parse error handling so a non-JSON LLM response
        // doesn't blow up the outer try/catch with an opaque message.
        let parsed;
        try {
            parsed = JSON.parse(response.content);
        }
        catch (parseErr) {
            log.warn({ snippet: response.content.slice(0, 200), err: parseErr.message }, 'router: LLM returned non-JSON, falling back');
            return { intent: 'product_inquiry', confidence: 0.3, suggestedTier: 'brain' };
        }
        const validated = routerResultSchema.safeParse({
            ...parsed,
            suggestedTier: INTENT_TIER_MAP[parsed.intent] ?? 'brain',
        });
        if (validated.success) {
            log.debug({ intent: validated.data.intent, confidence: validated.data.confidence, tier: validated.data.suggestedTier, latencyMs: response.latencyMs }, 'Intent classified via NVIDIA NIM');
            return validated.data;
        }
        log.warn({ parsed, errors: validated.error.issues }, 'Invalid router response, using fallback');
    }
    catch (err) {
        log.error({ error: err instanceof Error ? err.message : String(err) }, 'Router classification failed');
    }
    // Fallback — عند فشل التصنيف، افترض أنها استفسار يحتاج الدماغ
    return { intent: 'product_inquiry', confidence: 0.3, suggestedTier: 'brain' };
}
// ─── Quick Classifier ────────────────────────────────────────────────
/** تصنيف سريع بدون LLM للحالات الواضحة — يوفر وقت وتكلفة */
function quickClassify(text, context) {
    const trimmed = text.trim().toLowerCase();
    // وسائط
    if (context?.hasMedia) {
        if (context.mediaType === 'audio') {
            return { intent: 'voice_note', confidence: 0.95, suggestedTier: 'brain' };
        }
        if (context.mediaType === 'image') {
            return { intent: 'image', confidence: 0.95, suggestedTier: 'brain' };
        }
        if (context.mediaType === 'document') {
            return { intent: 'document', confidence: 0.95, suggestedTier: 'brain' };
        }
    }
    // تحيات
    const greetings = ['السلام عليكم', 'مرحبا', 'هلا', 'اهلا', 'هاي', 'hi', 'hello', 'مساء الخير', 'صباح الخير', 'السلام'];
    if (greetings.some(g => trimmed.startsWith(g)) && trimmed.length < 50) {
        return { intent: 'greeting', confidence: 0.95, suggestedTier: 'flash' };
    }
    // تصعيد لبشري
    const escalationPhrases = ['أبي أكلم شخص', 'ابي اكلم شخص', 'وكيل بشري', 'أبغى شخص حقيقي', 'كلمني مع شخص', 'talk to human', 'real person'];
    if (escalationPhrases.some(p => trimmed.includes(p))) {
        return { intent: 'escalate_to_human', confidence: 0.95, suggestedTier: 'flash' };
    }
    return null;
}
//# sourceMappingURL=router.js.map