/** * Workflow Recommendations Component * * Displays proactive workflow recommendations from the Adaptive Intelligence Mesh. * Shows detected patterns and suggested workflows based on user behavior. */ import React, { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { useMeshStore } from '../store/meshStore'; import type { WorkflowRecommendation, BehaviorPattern, PatternTypeVariant } from '../lib/intelligence-client'; // === Main Component === export const WorkflowRecommendations: React.FC = () => { const { recommendations, patterns, isLoading, error, analyze, acceptRecommendation, dismissRecommendation, } = useMeshStore(); const [selectedPattern, setSelectedPattern] = useState(null); useEffect(() => { // Initial analysis analyze(); }, [analyze]); if (isLoading) { return (
Analyzing patterns...
); } if (error) { return (

{error}

); } return (
{/* Recommendations Section */}

💡 Recommended Workflows {recommendations.length > 0 && ( {recommendations.length} )}

{recommendations.length === 0 ? (

No recommendations available yet.

Continue using the app to build up behavior patterns.

) : (
{recommendations.map((rec) => ( acceptRecommendation(rec.id)} onDismiss={() => dismissRecommendation(rec.id)} /> ))}
)}
{/* Detected Patterns Section */}

📊 Detected Patterns {patterns.length > 0 && ( {patterns.length} )}

{patterns.length === 0 ? (

No patterns detected yet.

) : (
{patterns.map((pattern) => ( setSelectedPattern( selectedPattern === pattern.id ? null : pattern.id ) } /> ))}
)}
); }; // === Sub-Components === interface RecommendationCardProps { recommendation: WorkflowRecommendation; onAccept: () => void; onDismiss: () => void; } const RecommendationCard: React.FC = ({ recommendation, onAccept, onDismiss, }) => { const confidencePercent = Math.round(recommendation.confidence * 100); const getConfidenceColor = (confidence: number) => { if (confidence >= 0.8) return 'text-green-400'; if (confidence >= 0.6) return 'text-yellow-400'; return 'text-orange-400'; }; return (

{recommendation.pipeline_id}

{confidencePercent}%

{recommendation.reason}

{/* Suggested Inputs */} {Object.keys(recommendation.suggested_inputs).length > 0 && (

Suggested inputs:

{Object.entries(recommendation.suggested_inputs).map( ([key, value]) => ( {key}: {String(value).slice(0, 20)} ) )}
)} {/* Matched Patterns */} {recommendation.patterns_matched.length > 0 && (
Based on {recommendation.patterns_matched.length} pattern(s)
)}
{/* Actions */}
{/* Confidence Bar */}
= 0.8 ? 'bg-green-500' : recommendation.confidence >= 0.6 ? 'bg-yellow-500' : 'bg-orange-500' }`} />
); }; interface PatternCardProps { pattern: BehaviorPattern; isSelected: boolean; onClick: () => void; } const PatternCard: React.FC = ({ pattern, isSelected, onClick, }) => { const getPatternTypeLabel = (type: PatternTypeVariant | string) => { // Handle object format const typeStr = typeof type === 'string' ? type : type.type; switch (typeStr) { case 'SkillCombination': return { label: 'Skill Combo', icon: '⚡' }; case 'TemporalTrigger': return { label: 'Time Trigger', icon: '⏰' }; case 'TaskPipelineMapping': return { label: 'Task Mapping', icon: '🔄' }; case 'InputPattern': return { label: 'Input Pattern', icon: '📝' }; default: return { label: typeStr, icon: '📊' }; } }; const { label, icon } = getPatternTypeLabel(pattern.pattern_type as PatternTypeVariant); const confidencePercent = Math.round(pattern.confidence * 100); return (
{icon} {label}
{pattern.frequency}x used = 0.6 ? 'text-green-400' : 'text-yellow-400' }`} > {confidencePercent}%
{isSelected && (
ID:{' '} {pattern.id}
First seen:{' '} {new Date(pattern.first_occurrence).toLocaleDateString()}
Last seen:{' '} {new Date(pattern.last_occurrence).toLocaleDateString()}
{pattern.context.intent && (
Intent:{' '} {pattern.context.intent}
)}
)}
); }; export default WorkflowRecommendations;