/**
 * src/agent/brain.ts
 * الدماغ الرئيسي للوكيل — يعالج الرسائل ويولد الردود
 * The core: receives message → classifies → builds prompt → calls model → (tools) → response
 */
import { type RouterResult } from './router.js';
import { type OptimizationResult } from '../billing/cost-optimizer.js';
export interface MessageContext {
    mediaType?: 'text' | 'image' | 'audio' | 'document' | 'video' | 'sticker';
    extractedText?: string;
    mediaUrl?: string;
    recentMessages?: Array<{
        role: 'user' | 'assistant';
        content: string;
    }>;
    customerName?: string;
    customerPhone?: string;
    additionalInstructions?: string;
    /** which surface the user is on — affects response length + style. Default 'whatsapp'. */
    channel?: 'web' | 'whatsapp';
    /**
     * Tracks indirect-recursion depth across cron `agentTurn` payloads. (Audit C5.)
     * A scheduled job triggers processMessage; if that turn schedules ANOTHER
     * cron with kind='agentTurn', the next fire could recurse. Without this cap,
     * a poisoned message could create infinite cron-fed turns across days.
     * Capped at 3 levels by default (configurable via MUASSIS_MAX_AGENT_RECURSION).
     */
    recursionDepth?: number;
}
/**
 * Event emitted while processMessage runs — observed by SSE/WebSocket
 * surfaces so the dashboard can show "thinking → calling X → got result"
 * cards in real time. Optional; processMessage works fine without an
 * onEvent callback.
 */
export type BrainEvent = {
    type: 'thinking';
    intent?: string;
    tier?: string;
} | {
    type: 'skill_match';
    skills: Array<{
        name: string;
        score: number;
    }>;
} | {
    type: 'tool_call_start';
    name: string;
    args: unknown;
} | {
    type: 'tool_call_end';
    name: string;
    success: boolean;
    output: string;
    durationMs: number;
    data?: unknown;
} | {
    type: 'plan_announced';
    plan: Array<{
        step: number;
        description: string;
        tool: string;
    }>;
    expectedOutcome: string;
} | {
    type: 'plan_step_complete';
    step: number;
    tool: string;
    success: boolean;
    outputExcerpt: string;
} | {
    type: 'plan_done';
    allStepsOk: boolean;
    stepCount: number;
} | {
    type: 'token';
    text: string;
} | {
    type: 'response';
    text: string;
} | {
    type: 'error';
    message: string;
} | {
    type: 'done';
    latencyMs: number;
    tokens: {
        input: number;
        output: number;
    };
} | {
    type: 'artifact_ready';
    name: string;
    path: string;
    mimeType: string | null;
};
export interface ArtifactInfo {
    path: string;
    toolName: string;
    mimeType: string | null;
}
export interface ProcessMessageOptions {
    budgetAware?: boolean;
    enableTools?: boolean;
    maxToolLoops?: number;
    onEvent?: (event: BrainEvent) => void;
    /**
     * (v2.5.5) Called whenever a tool produces a file artifact. The delivery
     * layer (WhatsApp/Telegram) wires this up so files automatically attach
     * as media in the outbound message — no "saved to your desktop, go look
     * for it" hand-waving. Local channels still get the OS-open via the
     * brain's auto-show hook; this callback is the cross-channel mechanism.
     */
    onArtifact?: (artifact: ArtifactInfo) => void;
}
export interface BrainResponse {
    response: string;
    intent: RouterResult;
    model_used: string;
    tokens: {
        input: number;
        output: number;
    };
    cost: number;
    latencyMs: number;
    failedOver: boolean;
    costOptimization?: OptimizationResult;
    toolsExecuted?: Array<{
        name: string;
        success: boolean;
        output: string;
    }>;
}
export declare function processMessage(tenantId: string, customerId: string, message: string, context?: MessageContext, options?: ProcessMessageOptions): Promise<BrainResponse>;
//# sourceMappingURL=brain.d.ts.map