Newer
Older
cortex-hub / frontend / src / features / agents / components / AgentDrillDown.js
import React, { useState } from 'react';
import FileSystemNavigator from '../../../shared/components/FileSystemNavigator';
import { useAgentDrillDown } from '../hooks/useAgentDrillDown';
import DrillDownHeader from './drilldown/DrillDownHeader';
import ChatTracker from './drilldown/ChatTracker';
import EvaluationPanel from './drilldown/EvaluationPanel';
import ConfigPanel from './drilldown/ConfigPanel';
import MetricsPanel from './drilldown/MetricsPanel';

export default function AgentDrillDown({ agentId, onNavigate }) {
    const hookData = useAgentDrillDown(agentId);
    const {
        agent, chatHistory, loading, error, activeTab, setActiveTab,
        editConfig, setEditConfig, saving, userConfig, tokenUsage, tokenError,
        clearing, triggers, newTriggerType, setNewTriggerType, newCronValue, setNewCronValue,
        newIntervalValue, setNewIntervalValue, newDefaultPrompt, setNewDefaultPrompt,
        creatingTrigger, modalConfig, setModalConfig, nodes, allSkills, flippedCards, setFlippedCards,
        feedbackContent, rubricContent, coworkerContent, setCoworkerContent,
        historyLog, savingGroundTruth, selectedAuditId, setSelectedAuditId,
        runningSeconds, lastTotalConsumption, currentAction, lastAction, lastActionDuration,
        handleAction, handleClearHistory, handleSaveConfig, handleSaveGroundTruth, fetchData,
        handleAddTrigger, handleDeleteTrigger, handleFireTrigger, handleFireWebhook,
        handleResetMetrics, overrideText, setOverrideText, handleInjectOverride
    } = hookData;

    if (loading && !agent) return (
        <div className="flex h-screen items-center justify-center bg-[#070b14] text-white">
            <div className="animate-spin w-8 h-8 border-4 border-indigo-500 border-t-transparent rounded-full font-mono text-sm ml-4"></div>
        </div>
    );

    if (error) return (
        <div className="flex h-screen items-center justify-center bg-gray-950 text-red-500">
            Error loading Agent Drilldown: {error}
        </div>
    );

    return (
        <div className="flex flex-col flex-grow h-full bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 font-sans overflow-hidden">
            
            <DrillDownHeader 
                agent={agent} 
                onNavigate={onNavigate} 
                nodes={nodes} 
            />

            {/* Mobile View Toggle */}
            <div className="lg:hidden flex border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-800 sticky top-0 z-20 overflow-x-auto no-scrollbar">
                {['chat', 'evaluation', 'config', 'workspace', 'metrics'].map(tab => (
                    <button 
                        key={tab}
                        onClick={() => setActiveTab(tab)} 
                        className={`flex-1 min-w-[100px] px-4 py-3 text-[10px] font-black uppercase tracking-widest transition-all border-b-2 ${activeTab === tab || (tab === 'chat' && !['config', 'workspace', 'metrics', 'evaluation'].includes(activeTab)) ? 'border-indigo-500 text-indigo-500 bg-indigo-50/10' : 'border-transparent text-gray-500'}`}
                    >
                        {tab === 'chat' ? 'Live Chat' : tab.charAt(0).toUpperCase() + tab.slice(1)}
                    </button>
                ))}
            </div>

            {/* Main Content Area */}
            <div className="flex-1 grid grid-cols-1 lg:grid-cols-[1.8fr_2.2fr] overflow-hidden gap-1 p-1 bg-gray-200 dark:bg-gray-950">
                
                {/* Left Pane: Chat Tracker */}
                <div className={`flex flex-col overflow-hidden ${activeTab === 'evaluation' || activeTab === 'config' || activeTab === 'workspace' || activeTab === 'metrics' ? 'hidden lg:flex' : 'flex'}`}>
                    <ChatTracker 
                        agent={agent}
                        chatHistory={chatHistory}
                        handleClearHistory={handleClearHistory}
                        handleAction={handleAction}
                        clearing={clearing}
                        editConfig={editConfig}
                        currentAction={currentAction}
                        lastAction={lastAction}
                        lastActionDuration={lastActionDuration}
                        runningSeconds={runningSeconds}
                    />
                </div>

                {/* Right Pane: Multi-Tab Dashboard */}
                <div className={`flex flex-col bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800/80 rounded-xl overflow-hidden relative shadow-lg ${activeTab === 'chat' ? 'hidden lg:flex' : 'flex'}`}>
                    {/* Desktop Tab Switcher */}
                    <div className="hidden lg:flex bg-gray-50 dark:bg-gray-950 border-b border-gray-200 dark:border-gray-800/80 px-4 pt-2 gap-1 shrink-0">
                        {['evaluation', 'config', 'workspace', 'metrics'].map(tab => (
                            <button 
                                key={tab}
                                onClick={() => setActiveTab(tab)}
                                className={`px-4 py-2 text-xs font-bold uppercase tracking-widest rounded-t-lg transition-colors ${activeTab === tab ? 'bg-white dark:bg-gray-900 text-indigo-500 border-t border-l border-r border-gray-200 dark:border-gray-800/80 -mb-px' : 'text-gray-500 hover:text-gray-400'}`}
                            >
                                {tab.charAt(0).toUpperCase() + tab.slice(1)}
                            </button>
                        ))}
                    </div>

                    <div className="flex-1 overflow-hidden relative">
                        {activeTab === 'evaluation' && (
                            <EvaluationPanel 
                                chatHistory={chatHistory}
                                selectedAuditId={selectedAuditId}
                                setSelectedAuditId={setSelectedAuditId}
                                feedbackContent={feedbackContent}
                                rubricContent={rubricContent}
                                historyLog={historyLog}
                                coworkerContent={coworkerContent}
                                setCoworkerContent={setCoworkerContent}
                                handleSaveGroundTruth={handleSaveGroundTruth}
                                savingGroundTruth={savingGroundTruth}
                                editConfig={editConfig}
                                fetchData={fetchData}
                                agent={agent}
                            />
                        )}

                        {activeTab === 'config' && (
                            <ConfigPanel 
                                editConfig={editConfig}
                                setEditConfig={setEditConfig}
                                saving={saving}
                                handleSaveConfig={handleSaveConfig}
                                nodes={nodes}
                                allSkills={allSkills}
                                triggers={triggers}
                                handleAddTrigger={handleAddTrigger}
                                handleDeleteTrigger={handleDeleteTrigger}
                                handleFireTrigger={handleFireTrigger}
                                handleFireWebhook={handleFireWebhook}
                                newTriggerType={newTriggerType}
                                setNewTriggerType={setNewTriggerType}
                                newCronValue={newCronValue}
                                setNewCronValue={setNewCronValue}
                                newIntervalValue={newIntervalValue}
                                setNewIntervalValue={setNewIntervalValue}
                                newDefaultPrompt={newDefaultPrompt}
                                setNewDefaultPrompt={setNewDefaultPrompt}
                                creatingTrigger={creatingTrigger}
                                overrideText={overrideText}
                                setOverrideText={setOverrideText}
                                handleInjectOverride={handleInjectOverride}
                                agentId={agentId}
                            />
                        )}

                        {activeTab === 'workspace' && (
                            <div className="flex flex-col h-full bg-[#0d0d0d]">
                                <FileSystemNavigator 
                                    nodeId={agent?.mesh_node_id || "hub"} 
                                    sessionId={agent?.session?.sync_workspace_id || agent?.session_id} 
                                />
                            </div>
                        )}

                        {activeTab === 'metrics' && (
                            <MetricsPanel 
                                agent={agent}
                                tokenUsage={tokenUsage}
                                tokenError={tokenError}
                                flippedCards={flippedCards}
                                setFlippedCards={setFlippedCards}
                                handleResetMetrics={handleResetMetrics}
                                clearing={clearing}
                            />
                        )}
                    </div>
                </div>
            </div>

            {/* Modal Dialogs */}
            {modalConfig && (
                <div className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200">
                    <div className="bg-white dark:bg-gray-900 rounded-3xl p-8 max-w-sm w-full shadow-2xl border border-gray-200 dark:border-gray-800 animate-in zoom-in-95 duration-200">
                        <div className={`w-12 h-12 rounded-2xl flex items-center justify-center mb-6 ${modalConfig.type === 'error' ? 'bg-red-100 dark:bg-red-500/20 text-red-600' : 'bg-emerald-100 dark:bg-emerald-500/20 text-emerald-600'}`}>
                            {modalConfig.type === 'error' ? (
                                <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
                            ) : (
                                <svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /></svg>
                            )}
                        </div>
                        <h3 className="text-xl font-black mb-2 text-gray-900 dark:text-white uppercase tracking-tight">{modalConfig.title}</h3>
                        <p className="text-gray-500 dark:text-gray-400 text-sm leading-relaxed mb-8">{modalConfig.message}</p>
                        <div className="flex gap-3">
                            {modalConfig.confirmAction ? (
                                <>
                                    <button 
                                        onClick={() => setModalConfig(null)}
                                        className="flex-1 px-4 py-3 rounded-xl bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white text-xs font-black uppercase tracking-widest hover:bg-gray-200 dark:hover:bg-gray-700 transition-all"
                                    >
                                        Cancel
                                    </button>
                                    <button 
                                        onClick={() => {
                                            modalConfig.confirmAction();
                                            setModalConfig(null);
                                        }}
                                        className="flex-1 px-4 py-3 rounded-xl bg-red-600 text-white text-xs font-black uppercase tracking-widest hover:bg-red-700 transition-all shadow-lg shadow-red-500/20"
                                    >
                                        {modalConfig.confirmText || 'Confirm'}
                                    </button>
                                </>
                            ) : (
                                <button 
                                    onClick={() => setModalConfig(null)}
                                    className="w-full px-4 py-3 rounded-xl bg-indigo-600 text-white text-xs font-black uppercase tracking-widest hover:bg-indigo-700 transition-all shadow-lg shadow-indigo-500/20"
                                >
                                    Dismiss
                                </button>
                            )}
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
}