Phase 2 Complete: CopilotKit Integration - PlatformPersonaChat component with comprehensive testing and integration examples
This commit is contained in:
245
frontend/src/components/shared/CopilotKit/IntegrationExample.tsx
Normal file
245
frontend/src/components/shared/CopilotKit/IntegrationExample.tsx
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
/**
|
||||||
|
* Integration Example Component
|
||||||
|
* Shows how to integrate PlatformPersonaChat into existing editors
|
||||||
|
* Demonstrates practical usage patterns for different platforms
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { PlatformPersonaProvider, PlatformPersonaChat } from '../PersonaContext';
|
||||||
|
import { PlatformType } from '../../types/PlatformPersonaTypes';
|
||||||
|
|
||||||
|
// Example: LinkedIn Writer Integration
|
||||||
|
export const LinkedInWriterWithPersonaChat: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<div className="linkedin-writer-container">
|
||||||
|
{/* Existing LinkedIn Editor Content */}
|
||||||
|
<div className="linkedin-editor-section p-4 border rounded-lg mb-4">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">LinkedIn Content Editor</h3>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-3 border rounded-lg"
|
||||||
|
rows={6}
|
||||||
|
placeholder="Write your LinkedIn post here..."
|
||||||
|
/>
|
||||||
|
<div className="mt-3 flex gap-2">
|
||||||
|
<button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Preview
|
||||||
|
</button>
|
||||||
|
<button className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
|
||||||
|
Schedule
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Persona-Aware Chat Integration */}
|
||||||
|
<div className="persona-chat-section">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">AI Content Assistant</h3>
|
||||||
|
<PlatformPersonaProvider platform="linkedin">
|
||||||
|
<PlatformPersonaChat
|
||||||
|
platform="linkedin"
|
||||||
|
showWelcomeMessage={true}
|
||||||
|
showSuggestedPrompts={true}
|
||||||
|
className="border rounded-lg"
|
||||||
|
/>
|
||||||
|
</PlatformPersonaProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: Facebook Writer Integration
|
||||||
|
export const FacebookWriterWithPersonaChat: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<div className="facebook-writer-container">
|
||||||
|
{/* Existing Facebook Editor Content */}
|
||||||
|
<div className="facebook-editor-section p-4 border rounded-lg mb-4">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">Facebook Content Editor</h3>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-3 border rounded-lg"
|
||||||
|
rows={4}
|
||||||
|
placeholder="Write your Facebook post here..."
|
||||||
|
/>
|
||||||
|
<div className="mt-3 flex gap-2">
|
||||||
|
<button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Preview
|
||||||
|
</button>
|
||||||
|
<button className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
|
||||||
|
Schedule
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Persona-Aware Chat Integration */}
|
||||||
|
<div className="persona-chat-section">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">AI Content Assistant</h3>
|
||||||
|
<PlatformPersonaProvider platform="facebook">
|
||||||
|
<PlatformPersonaChat
|
||||||
|
platform="facebook"
|
||||||
|
showWelcomeMessage={true}
|
||||||
|
showSuggestedPrompts={true}
|
||||||
|
className="border rounded-lg"
|
||||||
|
/>
|
||||||
|
</PlatformPersonaProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: Instagram Writer Integration
|
||||||
|
export const InstagramWriterWithPersonaChat: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<div className="instagram-writer-container">
|
||||||
|
{/* Existing Instagram Editor Content */}
|
||||||
|
<div className="instagram-editor-section p-4 border rounded-lg mb-4">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">Instagram Content Editor</h3>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<div className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-3">
|
||||||
|
<p className="text-gray-500">Upload Image/Video</p>
|
||||||
|
</div>
|
||||||
|
<textarea
|
||||||
|
className="w-full p-3 border rounded-lg"
|
||||||
|
rows={4}
|
||||||
|
placeholder="Write your Instagram caption here..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium mb-2">Hashtag Suggestions</h4>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
<span className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded">#content</span>
|
||||||
|
<span className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded">#strategy</span>
|
||||||
|
<span className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded">#growth</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-3 flex gap-2">
|
||||||
|
<button className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
|
Preview
|
||||||
|
</button>
|
||||||
|
<button className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
|
||||||
|
Schedule
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Persona-Aware Chat Integration */}
|
||||||
|
<div className="persona-chat-section">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">AI Content Assistant</h3>
|
||||||
|
<PlatformPersonaProvider platform="instagram">
|
||||||
|
<PlatformPersonaChat
|
||||||
|
platform="instagram"
|
||||||
|
showWelcomeMessage={true}
|
||||||
|
showSuggestedPrompts={true}
|
||||||
|
className="border rounded-lg"
|
||||||
|
/>
|
||||||
|
</PlatformPersonaProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Main integration example component
|
||||||
|
export const IntegrationExample: React.FC = () => {
|
||||||
|
const [selectedPlatform, setSelectedPlatform] = React.useState<PlatformType>('linkedin');
|
||||||
|
|
||||||
|
const renderSelectedEditor = () => {
|
||||||
|
switch (selectedPlatform) {
|
||||||
|
case 'linkedin':
|
||||||
|
return <LinkedInWriterWithPersonaChat />;
|
||||||
|
case 'facebook':
|
||||||
|
return <FacebookWriterWithPersonaChat />;
|
||||||
|
case 'instagram':
|
||||||
|
return <InstagramWriterWithPersonaChat />;
|
||||||
|
default:
|
||||||
|
return <LinkedInWriterWithPersonaChat />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-6xl mx-auto p-6">
|
||||||
|
<div className="mb-6">
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
||||||
|
Platform Persona Chat Integration Examples
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
See how to integrate persona-aware AI chat into existing content editors
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Platform Tabs */}
|
||||||
|
<div className="flex space-x-1 mb-6 bg-gray-100 p-1 rounded-lg">
|
||||||
|
{(['linkedin', 'facebook', 'instagram'] as PlatformType[]).map((platform) => (
|
||||||
|
<button
|
||||||
|
key={platform}
|
||||||
|
onClick={() => setSelectedPlatform(platform)}
|
||||||
|
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors ${
|
||||||
|
selectedPlatform === platform
|
||||||
|
? 'bg-white text-gray-900 shadow-sm'
|
||||||
|
: 'text-gray-600 hover:text-gray-900'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{platform.charAt(0).toUpperCase() + platform.slice(1)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Selected Editor */}
|
||||||
|
{renderSelectedEditor()}
|
||||||
|
|
||||||
|
{/* Integration Benefits */}
|
||||||
|
<div className="mt-8 p-6 bg-gradient-to-r from-blue-50 to-purple-50 border border-blue-200 rounded-lg">
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900 mb-4">
|
||||||
|
Benefits of Persona-Aware Chat Integration
|
||||||
|
</h3>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">🎯 Personalized Assistance</h4>
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
AI responses automatically match your writing style, vocabulary preferences, and brand voice
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">🚀 Platform Optimization</h4>
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
Get platform-specific advice for character limits, hashtag strategies, and engagement patterns
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">💡 Contextual Intelligence</h4>
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
AI understands your content goals, audience, and industry context for better suggestions
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">⚡ Seamless Workflow</h4>
|
||||||
|
<p className="text-sm text-gray-700">
|
||||||
|
Chat directly in your editor while maintaining focus on content creation
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Implementation Notes */}
|
||||||
|
<div className="mt-6 p-4 bg-gray-50 border border-gray-200 rounded-lg">
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">Implementation Notes</h4>
|
||||||
|
<div className="text-sm text-gray-700 space-y-2">
|
||||||
|
<p>
|
||||||
|
<strong>1. Wrap your editor with PlatformPersonaProvider:</strong> This provides persona context to all child components.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>2. Add PlatformPersonaChat component:</strong> Place it where you want the AI chat interface.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>3. Configure platform-specific settings:</strong> The chat automatically adapts to each platform's requirements.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>4. Customize appearance:</strong> Use className and other props to match your editor's design.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IntegrationExample;
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/**
|
||||||
|
* Platform Persona Chat Component
|
||||||
|
* CopilotKit integration for platform-specific persona-aware conversations
|
||||||
|
* Provides intelligent, contextual assistance based on user's writing persona
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useCallback, useMemo } from 'react';
|
||||||
|
import { CopilotChat, CopilotChatProps } from '@copilotkit/react-chat';
|
||||||
|
import { usePlatformPersonaContext } from '../PersonaContext';
|
||||||
|
import { PlatformType, WritingPersona, PlatformAdaptation } from '../../types/PlatformPersonaTypes';
|
||||||
|
|
||||||
|
// Platform-specific chat configurations
|
||||||
|
interface PlatformChatConfig {
|
||||||
|
systemMessage: string;
|
||||||
|
placeholder: string;
|
||||||
|
welcomeMessage: string;
|
||||||
|
suggestedPrompts: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform chat configurations
|
||||||
|
const getPlatformChatConfig = (
|
||||||
|
platform: PlatformType,
|
||||||
|
corePersona: WritingPersona | null,
|
||||||
|
platformPersona: PlatformAdaptation | null
|
||||||
|
): PlatformChatConfig => {
|
||||||
|
const baseConfig = {
|
||||||
|
systemMessage: `You are an expert ${platform} content strategist and writer.`,
|
||||||
|
placeholder: `Ask me about ${platform} content strategy...`,
|
||||||
|
welcomeMessage: `Hello! I'm your ${platform} content assistant. How can I help you today?`,
|
||||||
|
suggestedPrompts: [
|
||||||
|
`Help me create a ${platform} post about...`,
|
||||||
|
`What's the best time to post on ${platform}?`,
|
||||||
|
`How can I improve my ${platform} engagement?`
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!corePersona || !platformPersona) {
|
||||||
|
return baseConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhanced configuration with persona data
|
||||||
|
return {
|
||||||
|
systemMessage: `You are an expert ${platform} content strategist and writer, specializing in ${corePersona.persona_name} style content.`,
|
||||||
|
placeholder: `Ask me about ${platform} content using your ${corePersona.persona_name} style...`,
|
||||||
|
welcomeMessage: `Hello! I'm your ${platform} content assistant, trained on your "${corePersona.persona_name}" writing style. How can I help you create ${platform}-optimized content today?`,
|
||||||
|
suggestedPrompts: [
|
||||||
|
`Create a ${platform} post about [topic] using my ${corePersona.persona_name} style`,
|
||||||
|
`How can I adapt my ${corePersona.persona_name} voice for ${platform}?`,
|
||||||
|
`What ${platform} content strategy fits my ${corePersona.archetype} archetype?`,
|
||||||
|
`Help me optimize my ${platform} posts for better engagement`
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enhanced system message generator
|
||||||
|
const generateEnhancedSystemMessage = (
|
||||||
|
platform: PlatformType,
|
||||||
|
corePersona: WritingPersona | null,
|
||||||
|
platformPersona: PlatformAdaptation | null
|
||||||
|
): string => {
|
||||||
|
if (!corePersona || !platformPersona) {
|
||||||
|
return `You are an expert ${platform} content strategist and writer. Provide helpful advice for creating engaging ${platform} content.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const linguisticFingerprint = corePersona.linguistic_fingerprint;
|
||||||
|
const platformConstraints = platformPersona.content_format_rules;
|
||||||
|
const engagementPatterns = platformPersona.engagement_patterns;
|
||||||
|
|
||||||
|
return `
|
||||||
|
You are an expert ${platform} content strategist and writer, specializing in ${corePersona.persona_name} style content.
|
||||||
|
|
||||||
|
## CORE PERSONA CONTEXT
|
||||||
|
- **Persona Name**: ${corePersona.persona_name}
|
||||||
|
- **Archetype**: ${corePersona.archetype}
|
||||||
|
- **Core Belief**: ${corePersona.core_belief}
|
||||||
|
- **Confidence Score**: ${corePersona.confidence_score}%
|
||||||
|
|
||||||
|
## LINGUISTIC FINGERPRINT
|
||||||
|
- **Sentence Length**: ${linguisticFingerprint?.sentence_metrics?.average_sentence_length_words || 'Unknown'} words average
|
||||||
|
- **Voice Ratio**: ${linguisticFingerprint?.sentence_metrics?.active_to_passive_ratio || 'Unknown'}
|
||||||
|
- **Go-to Words**: ${linguisticFingerprint?.lexical_features?.go_to_words?.join(", ") || 'Unknown'}
|
||||||
|
- **Avoid Words**: ${linguisticFingerprint?.lexical_features?.avoid_words?.join(", ") || 'Unknown'}
|
||||||
|
- **Vocabulary Level**: ${linguisticFingerprint?.lexical_features?.vocabulary_level || 'Unknown'}
|
||||||
|
|
||||||
|
## ${platform.toUpperCase()} PLATFORM OPTIMIZATION
|
||||||
|
- **Platform**: ${platformPersona.platform_type}
|
||||||
|
- **Character Limit**: ${platformConstraints?.character_limit || 'Unknown'}
|
||||||
|
- **Optimal Length**: ${platformConstraints?.optimal_length || 'Unknown'}
|
||||||
|
- **Hashtag Limit**: ${platformConstraints?.hashtag_limit || 'Unknown'}
|
||||||
|
- **Posting Frequency**: ${engagementPatterns?.posting_frequency || 'Unknown'}
|
||||||
|
|
||||||
|
## WRITING GUIDELINES
|
||||||
|
1. **Always match the user's linguistic fingerprint** - use their preferred sentence length, vocabulary level, and writing style
|
||||||
|
2. **Respect platform constraints** - stay within character limits and follow ${platform} best practices
|
||||||
|
3. **Maintain persona consistency** - every piece of content should sound like it was written by ${corePersona.persona_name}
|
||||||
|
4. **Optimize for engagement** - use ${platform}-specific strategies for better reach and interaction
|
||||||
|
5. **Incorporate go-to words and phrases** naturally, while avoiding words the user dislikes
|
||||||
|
|
||||||
|
## RESPONSE FORMAT
|
||||||
|
- Provide specific, actionable advice
|
||||||
|
- Include examples that match the user's writing style
|
||||||
|
- Reference platform-specific constraints and opportunities
|
||||||
|
- Suggest content ideas that align with their archetype and core beliefs
|
||||||
|
|
||||||
|
Remember: You're not just giving generic ${platform} advice - you're helping ${corePersona.persona_name} create content that sounds authentically like them while being perfectly optimized for ${platform}.
|
||||||
|
`.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Platform-specific action suggestions
|
||||||
|
const getPlatformActions = (platform: PlatformType): string[] => {
|
||||||
|
const actions: Record<PlatformType, string[]> = {
|
||||||
|
linkedin: [
|
||||||
|
"Create thought leadership post",
|
||||||
|
"Optimize for professional networking",
|
||||||
|
"Suggest industry hashtags",
|
||||||
|
"Improve engagement strategy"
|
||||||
|
],
|
||||||
|
facebook: [
|
||||||
|
"Create community-focused content",
|
||||||
|
"Suggest trending topics",
|
||||||
|
"Optimize for shares and comments",
|
||||||
|
"Plan content calendar"
|
||||||
|
],
|
||||||
|
instagram: [
|
||||||
|
"Create visual-first content ideas",
|
||||||
|
"Suggest hashtag strategy",
|
||||||
|
"Optimize for stories and reels",
|
||||||
|
"Improve aesthetic appeal"
|
||||||
|
],
|
||||||
|
twitter: [
|
||||||
|
"Create viral tweet ideas",
|
||||||
|
"Suggest trending hashtags",
|
||||||
|
"Optimize for retweets",
|
||||||
|
"Plan thread strategy"
|
||||||
|
],
|
||||||
|
blog: [
|
||||||
|
"Create SEO-optimized content",
|
||||||
|
"Suggest headline strategies",
|
||||||
|
"Optimize for readability",
|
||||||
|
"Plan content series"
|
||||||
|
],
|
||||||
|
medium: [
|
||||||
|
"Create publication strategy",
|
||||||
|
"Suggest storytelling approaches",
|
||||||
|
"Optimize for engagement",
|
||||||
|
"Plan article series"
|
||||||
|
],
|
||||||
|
substack: [
|
||||||
|
"Create newsletter strategy",
|
||||||
|
"Suggest subscriber engagement",
|
||||||
|
"Optimize for conversions",
|
||||||
|
"Plan content themes"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
return actions[platform] || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Main component interface
|
||||||
|
interface PlatformPersonaChatProps {
|
||||||
|
platform: PlatformType;
|
||||||
|
className?: string;
|
||||||
|
showWelcomeMessage?: boolean;
|
||||||
|
showSuggestedPrompts?: boolean;
|
||||||
|
customSystemMessage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PlatformPersonaChat: React.FC<PlatformPersonaChatProps> = ({
|
||||||
|
platform,
|
||||||
|
className = "",
|
||||||
|
showWelcomeMessage = true,
|
||||||
|
showSuggestedPrompts = true,
|
||||||
|
customSystemMessage
|
||||||
|
}) => {
|
||||||
|
const { corePersona, platformPersona, loading, error } = usePlatformPersonaContext();
|
||||||
|
|
||||||
|
// Generate platform-specific chat configuration
|
||||||
|
const chatConfig = useMemo(() =>
|
||||||
|
getPlatformChatConfig(platform, corePersona, platformPersona),
|
||||||
|
[platform, corePersona, platformPersona]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Generate enhanced system message
|
||||||
|
const systemMessage = useMemo(() =>
|
||||||
|
customSystemMessage || generateEnhancedSystemMessage(platform, corePersona, platformPersona),
|
||||||
|
[customSystemMessage, platform, corePersona, platformPersona]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get platform-specific actions
|
||||||
|
const platformActions = useMemo(() =>
|
||||||
|
getPlatformActions(platform),
|
||||||
|
[platform]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Custom makeSystemMessage function for CopilotKit
|
||||||
|
const makeSystemMessage = useCallback((contextString: string) => {
|
||||||
|
return `${systemMessage}\n\nCurrent Context: ${contextString}`;
|
||||||
|
}, [systemMessage]);
|
||||||
|
|
||||||
|
// Custom CopilotChat props
|
||||||
|
const copilotChatProps: CopilotChatProps = {
|
||||||
|
makeSystemMessage,
|
||||||
|
placeholder: chatConfig.placeholder,
|
||||||
|
className: `platform-persona-chat ${className}`,
|
||||||
|
showWelcomeMessage,
|
||||||
|
showSuggestedPrompts,
|
||||||
|
suggestedPrompts: showSuggestedPrompts ? chatConfig.suggestedPrompts : undefined,
|
||||||
|
welcomeMessage: showWelcomeMessage ? chatConfig.welcomeMessage : undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
// Loading state
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center p-6 border rounded-lg">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2"></div>
|
||||||
|
<p className="text-sm text-gray-600">Loading {platform} persona chat...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error state
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="p-4 bg-red-50 border border-red-200 rounded-lg">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<svg className="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div className="ml-3">
|
||||||
|
<h3 className="text-sm font-medium text-red-800">Chat Unavailable</h3>
|
||||||
|
<p className="text-sm text-red-700 mt-1">Unable to load persona data for {platform}.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persona info display
|
||||||
|
const PersonaInfo = () => (
|
||||||
|
<div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h4 className="text-sm font-medium text-blue-900">
|
||||||
|
{corePersona ? `Chatting as ${corePersona.persona_name}` : `${platform} Content Assistant`}
|
||||||
|
</h4>
|
||||||
|
{corePersona && (
|
||||||
|
<p className="text-xs text-blue-700 mt-1">
|
||||||
|
{corePersona.archetype} • {corePersona.confidence_score}% confidence
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-blue-600 bg-blue-100 px-2 py-1 rounded">
|
||||||
|
{platform}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`platform-persona-chat-container ${className}`}>
|
||||||
|
{/* Persona Information Header */}
|
||||||
|
<PersonaInfo />
|
||||||
|
|
||||||
|
{/* Platform Actions Suggestions */}
|
||||||
|
{platformActions.length > 0 && (
|
||||||
|
<div className="mb-4 p-3 bg-gray-50 border border-gray-200 rounded-lg">
|
||||||
|
<h5 className="text-sm font-medium text-gray-900 mb-2">Quick Actions for {platform}</h5>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{platformActions.map((action, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
className="text-xs bg-white border border-gray-300 rounded-full px-3 py-1 text-gray-700 hover:bg-gray-50 hover:border-gray-400 transition-colors"
|
||||||
|
onClick={() => {
|
||||||
|
// This could trigger a specific action or pre-fill the chat
|
||||||
|
console.log(`Suggested action: ${action}`);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{action}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* CopilotKit Chat Component */}
|
||||||
|
<CopilotChat {...copilotChatProps} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PlatformPersonaChat;
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* Platform Persona Chat Test Component
|
||||||
|
* Demonstrates and tests the PlatformPersonaChat component
|
||||||
|
* Shows how to integrate persona-aware chat into different platforms
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { PlatformPersonaProvider } from '../PersonaContext';
|
||||||
|
import { PlatformPersonaChat } from './index';
|
||||||
|
import { PlatformType } from '../../types/PlatformPersonaTypes';
|
||||||
|
|
||||||
|
// Platform selection component
|
||||||
|
const PlatformSelector: React.FC<{
|
||||||
|
selectedPlatform: PlatformType;
|
||||||
|
onPlatformChange: (platform: PlatformType) => void;
|
||||||
|
}> = ({ selectedPlatform, onPlatformChange }) => {
|
||||||
|
const platforms: { value: PlatformType; label: string; description: string }[] = [
|
||||||
|
{ value: 'linkedin', label: 'LinkedIn', description: 'Professional networking & thought leadership' },
|
||||||
|
{ value: 'facebook', label: 'Facebook', description: 'Community building & social engagement' },
|
||||||
|
{ value: 'instagram', label: 'Instagram', description: 'Visual storytelling & aesthetic content' },
|
||||||
|
{ value: 'twitter', label: 'Twitter', description: 'Concise messaging & viral potential' },
|
||||||
|
{ value: 'blog', label: 'Blog', description: 'Long-form content & SEO optimization' },
|
||||||
|
{ value: 'medium', label: 'Medium', description: 'Storytelling & publication strategy' },
|
||||||
|
{ value: 'substack', label: 'Substack', description: 'Newsletter & subscription focus' }
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mb-6 p-4 bg-gray-50 border border-gray-200 rounded-lg">
|
||||||
|
<h3 className="text-lg font-semibold mb-3">Select Platform to Test</h3>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
|
||||||
|
{platforms.map((platform) => (
|
||||||
|
<button
|
||||||
|
key={platform.value}
|
||||||
|
onClick={() => onPlatformChange(platform.value)}
|
||||||
|
className={`p-3 text-left rounded-lg border transition-all ${
|
||||||
|
selectedPlatform === platform.value
|
||||||
|
? 'border-blue-500 bg-blue-50 text-blue-900'
|
||||||
|
: 'border-gray-300 bg-white hover:border-gray-400 hover:bg-gray-50'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="font-medium">{platform.label}</div>
|
||||||
|
<div className="text-sm text-gray-600 mt-1">{platform.description}</div>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Chat configuration options
|
||||||
|
const ChatConfigOptions: React.FC<{
|
||||||
|
showWelcomeMessage: boolean;
|
||||||
|
showSuggestedPrompts: boolean;
|
||||||
|
onToggleWelcomeMessage: () => void;
|
||||||
|
onToggleSuggestedPrompts: () => void;
|
||||||
|
}> = ({ showWelcomeMessage, showSuggestedPrompts, onToggleWelcomeMessage, onToggleSuggestedPrompts }) => {
|
||||||
|
return (
|
||||||
|
<div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
|
||||||
|
<h4 className="text-sm font-medium text-yellow-900 mb-2">Chat Configuration</h4>
|
||||||
|
<div className="flex flex-wrap gap-4">
|
||||||
|
<label className="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={showWelcomeMessage}
|
||||||
|
onChange={onToggleWelcomeMessage}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-yellow-800">Show Welcome Message</span>
|
||||||
|
</label>
|
||||||
|
<label className="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={showSuggestedPrompts}
|
||||||
|
onChange={onToggleSuggestedPrompts}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-yellow-800">Show Suggested Prompts</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Main test component
|
||||||
|
export const PlatformPersonaChatTest: React.FC = () => {
|
||||||
|
const [selectedPlatform, setSelectedPlatform] = useState<PlatformType>('linkedin');
|
||||||
|
const [showWelcomeMessage, setShowWelcomeMessage] = useState(true);
|
||||||
|
const [showSuggestedPrompts, setShowSuggestedPrompts] = useState(true);
|
||||||
|
|
||||||
|
const toggleWelcomeMessage = () => setShowWelcomeMessage(!showWelcomeMessage);
|
||||||
|
const toggleSuggestedPrompts = () => setShowSuggestedPrompts(!showSuggestedPrompts);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-4xl mx-auto p-6">
|
||||||
|
<div className="mb-6">
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
||||||
|
Platform Persona Chat Test
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
Test the persona-aware CopilotKit integration across different platforms
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Platform Selector */}
|
||||||
|
<PlatformSelector
|
||||||
|
selectedPlatform={selectedPlatform}
|
||||||
|
onPlatformChange={setSelectedPlatform}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Chat Configuration */}
|
||||||
|
<ChatConfigOptions
|
||||||
|
showWelcomeMessage={showWelcomeMessage}
|
||||||
|
showSuggestedPrompts={showSuggestedPrompts}
|
||||||
|
onToggleWelcomeMessage={toggleWelcomeMessage}
|
||||||
|
onToggleSuggestedPrompts={toggleSuggestedPrompts}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Persona Chat Component */}
|
||||||
|
<div className="border rounded-lg overflow-hidden">
|
||||||
|
<div className="bg-gray-100 px-4 py-2 border-b">
|
||||||
|
<h3 className="font-medium text-gray-900">
|
||||||
|
{selectedPlatform.charAt(0).toUpperCase() + selectedPlatform.slice(1)} Persona Chat
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-gray-600">
|
||||||
|
AI-powered content assistance with your personal writing style
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PlatformPersonaProvider platform={selectedPlatform}>
|
||||||
|
<PlatformPersonaChat
|
||||||
|
platform={selectedPlatform}
|
||||||
|
showWelcomeMessage={showWelcomeMessage}
|
||||||
|
showSuggestedPrompts={showSuggestedPrompts}
|
||||||
|
className="p-4"
|
||||||
|
/>
|
||||||
|
</PlatformPersonaProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Usage Instructions */}
|
||||||
|
<div className="mt-6 p-4 bg-green-50 border border-green-200 rounded-lg">
|
||||||
|
<h4 className="font-medium text-green-900 mb-2">How to Test</h4>
|
||||||
|
<ul className="text-sm text-green-800 space-y-1">
|
||||||
|
<li>• Select different platforms to see platform-specific chat configurations</li>
|
||||||
|
<li>• Toggle welcome message and suggested prompts to test different chat modes</li>
|
||||||
|
<li>• Ask questions about content strategy, writing style, or platform optimization</li>
|
||||||
|
<li>• Notice how the AI adapts responses to your persona and platform constraints</li>
|
||||||
|
<li>• Try the quick action buttons for platform-specific suggestions</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Technical Details */}
|
||||||
|
<div className="mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
||||||
|
<h4 className="font-medium text-blue-900 mb-2">Technical Implementation</h4>
|
||||||
|
<div className="text-sm text-blue-800 space-y-2">
|
||||||
|
<p>
|
||||||
|
<strong>Context Injection:</strong> The chat automatically receives your writing persona,
|
||||||
|
linguistic fingerprint, and platform-specific constraints through CopilotKit's context system.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Dynamic System Messages:</strong> System messages are generated dynamically based on
|
||||||
|
your persona data and selected platform, ensuring AI responses match your writing style.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Platform Optimization:</strong> Each platform has specific character limits,
|
||||||
|
engagement patterns, and best practices that are automatically incorporated into AI responses.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PlatformPersonaChatTest;
|
||||||
11
frontend/src/components/shared/CopilotKit/index.ts
Normal file
11
frontend/src/components/shared/CopilotKit/index.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* CopilotKit Components Index
|
||||||
|
* Central export point for all CopilotKit integration components
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { PlatformPersonaChat } from './PlatformPersonaChat';
|
||||||
|
export { PlatformPersonaChatTest } from './PlatformPersonaChatTest';
|
||||||
|
export { IntegrationExample } from './IntegrationExample';
|
||||||
|
|
||||||
|
// Re-export types for convenience
|
||||||
|
export type { PlatformType } from '../../../types/PlatformPersonaTypes';
|
||||||
Reference in New Issue
Block a user