Phase 1 Complete: React Context Layer - TypeScript interfaces and PlatformPersonaProvider implemented
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Persona Test Component
|
||||
* Simple component to test and demonstrate the PlatformPersonaProvider
|
||||
* This can be used to verify the implementation works correctly
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { PlatformPersonaProvider, usePlatformPersonaContext } from './index';
|
||||
import { PlatformType } from '../../../types/PlatformPersonaTypes';
|
||||
|
||||
// Test component that uses the context
|
||||
const PersonaDisplay: React.FC = () => {
|
||||
const {
|
||||
corePersona,
|
||||
platformPersona,
|
||||
platform,
|
||||
loading,
|
||||
error,
|
||||
refreshPersonas
|
||||
} = usePlatformPersonaContext();
|
||||
|
||||
if (loading) {
|
||||
return <div>Loading persona data...</div>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div>
|
||||
<p>Error: {error}</p>
|
||||
<button onClick={refreshPersonas}>Retry</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-4 border rounded-lg">
|
||||
<h3 className="text-lg font-semibold mb-4">Persona Data for {platform}</h3>
|
||||
|
||||
{/* Core Persona Display */}
|
||||
{corePersona && (
|
||||
<div className="mb-4 p-3 bg-blue-50 rounded">
|
||||
<h4 className="font-medium text-blue-900">Core Persona</h4>
|
||||
<p><strong>Name:</strong> {corePersona.persona_name}</p>
|
||||
<p><strong>Archetype:</strong> {corePersona.archetype}</p>
|
||||
<p><strong>Core Belief:</strong> {corePersona.core_belief}</p>
|
||||
<p><strong>Confidence:</strong> {corePersona.confidence_score}%</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Platform Persona Display */}
|
||||
{platformPersona && (
|
||||
<div className="mb-4 p-3 bg-green-50 rounded">
|
||||
<h4 className="font-medium text-green-900">Platform Optimization</h4>
|
||||
<p><strong>Platform:</strong> {platformPersona.platform_type}</p>
|
||||
<p><strong>Character Limit:</strong> {platformPersona.content_format_rules?.character_limit || 'N/A'}</p>
|
||||
<p><strong>Optimal Length:</strong> {platformPersona.content_format_rules?.optimal_length || 'N/A'}</p>
|
||||
<p><strong>Posting Frequency:</strong> {platformPersona.engagement_patterns?.posting_frequency || 'N/A'}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Linguistic Fingerprint Display */}
|
||||
{corePersona?.linguistic_fingerprint && (
|
||||
<div className="mb-4 p-3 bg-purple-50 rounded">
|
||||
<h4 className="font-medium text-purple-900">Linguistic Fingerprint</h4>
|
||||
<p><strong>Avg Sentence Length:</strong> {corePersona.linguistic_fingerprint.sentence_metrics.average_sentence_length_words} words</p>
|
||||
<p><strong>Voice Ratio:</strong> {corePersona.linguistic_fingerprint.sentence_metrics.active_to_passive_ratio}</p>
|
||||
<p><strong>Go-to Words:</strong> {corePersona.linguistic_fingerprint.lexical_features.go_to_words?.join(', ') || 'N/A'}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Refresh Button */}
|
||||
<button
|
||||
onClick={refreshPersonas}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
>
|
||||
Refresh Personas
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Main test component with provider
|
||||
interface PersonaTestComponentProps {
|
||||
platform: PlatformType;
|
||||
userId?: number;
|
||||
}
|
||||
|
||||
export const PersonaTestComponent: React.FC<PersonaTestComponentProps> = ({
|
||||
platform,
|
||||
userId = 1
|
||||
}) => {
|
||||
return (
|
||||
<PlatformPersonaProvider platform={platform} userId={userId}>
|
||||
<PersonaDisplay />
|
||||
</PlatformPersonaProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default PersonaTestComponent;
|
||||
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* Platform Persona Provider
|
||||
* React Context provider for platform-specific persona data
|
||||
* Integrates with existing persona API client and injects data into CopilotKit
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
||||
import { useCopilotReadable } from '@copilotkit/react-core';
|
||||
import {
|
||||
WritingPersona,
|
||||
PlatformAdaptation,
|
||||
PlatformType,
|
||||
UserPersonasResponse,
|
||||
PlatformPersonaResponse
|
||||
} from '../../../types/PlatformPersonaTypes';
|
||||
import {
|
||||
getUserPersonas,
|
||||
getPlatformPersona
|
||||
} from '../../../api/persona';
|
||||
|
||||
// Context interface
|
||||
interface PlatformPersonaContextType {
|
||||
corePersona: WritingPersona | null;
|
||||
platformPersona: PlatformAdaptation | null;
|
||||
platform: PlatformType;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
refreshPersonas: () => Promise<void>;
|
||||
}
|
||||
|
||||
// Create the context
|
||||
const PlatformPersonaContext = createContext<PlatformPersonaContextType | null>(null);
|
||||
|
||||
// Provider props interface
|
||||
interface PlatformPersonaProviderProps {
|
||||
children: ReactNode;
|
||||
platform: PlatformType;
|
||||
userId?: number; // Default to 1 for now, can be enhanced with auth context later
|
||||
}
|
||||
|
||||
// Provider component
|
||||
export const PlatformPersonaProvider: React.FC<PlatformPersonaProviderProps> = ({
|
||||
children,
|
||||
platform,
|
||||
userId = 1
|
||||
}) => {
|
||||
// State management
|
||||
const [corePersona, setCorePersona] = useState<WritingPersona | null>(null);
|
||||
const [platformPersona, setPlatformPersona] = useState<PlatformAdaptation | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Fetch persona data function
|
||||
const fetchPersonas = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// Fetch both core persona and platform-specific data
|
||||
const [userPersonasResponse, platformPersonaResponse] = await Promise.all([
|
||||
getUserPersonas(userId),
|
||||
getPlatformPersona(userId, platform)
|
||||
]);
|
||||
|
||||
// Handle core persona data
|
||||
if (userPersonasResponse.personas && userPersonasResponse.personas.length > 0) {
|
||||
const primaryPersona = userPersonasResponse.personas[0];
|
||||
setCorePersona(primaryPersona);
|
||||
|
||||
console.log('✅ Core persona loaded:', {
|
||||
name: primaryPersona.persona_name,
|
||||
archetype: primaryPersona.archetype,
|
||||
confidence: primaryPersona.confidence_score
|
||||
});
|
||||
} else {
|
||||
console.warn('⚠️ No core personas found for user');
|
||||
setCorePersona(null);
|
||||
}
|
||||
|
||||
// Handle platform-specific persona data
|
||||
if (platformPersonaResponse) {
|
||||
setPlatformPersona(platformPersonaResponse);
|
||||
|
||||
console.log('✅ Platform persona loaded:', {
|
||||
platform: platformPersonaResponse.platform_type,
|
||||
characterLimit: platformPersonaResponse.content_format_rules?.character_limit,
|
||||
optimalLength: platformPersonaResponse.content_format_rules?.optimal_length
|
||||
});
|
||||
} else {
|
||||
console.warn(`⚠️ No platform-specific persona found for ${platform}`);
|
||||
setPlatformPersona(null);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching personas:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to fetch persona data');
|
||||
|
||||
// Set fallback data if available
|
||||
if (corePersona) {
|
||||
console.log('🔄 Using existing core persona data');
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Initial data fetch
|
||||
useEffect(() => {
|
||||
fetchPersonas();
|
||||
}, [platform, userId]);
|
||||
|
||||
// Refresh function for manual updates
|
||||
const refreshPersonas = async () => {
|
||||
await fetchPersonas();
|
||||
};
|
||||
|
||||
// Inject core persona into CopilotKit context
|
||||
useCopilotReadable({
|
||||
description: `Core writing persona: ${corePersona?.persona_name || 'Loading...'}`,
|
||||
value: corePersona,
|
||||
categories: ["core-persona", "writing-style", "user-preferences"],
|
||||
parentId: corePersona?.id?.toString()
|
||||
});
|
||||
|
||||
// Inject platform-specific persona into CopilotKit context
|
||||
useCopilotReadable({
|
||||
description: `${platform} platform optimization rules and constraints`,
|
||||
value: platformPersona,
|
||||
categories: ["platform-persona", platform, "content-optimization"],
|
||||
parentId: corePersona?.id?.toString()
|
||||
});
|
||||
|
||||
// Inject combined persona context for comprehensive understanding
|
||||
useCopilotReadable({
|
||||
description: `Complete ${platform} writing persona with linguistic fingerprint and platform optimization`,
|
||||
value: {
|
||||
core: corePersona,
|
||||
platform: platformPersona,
|
||||
combined: {
|
||||
persona_name: corePersona?.persona_name,
|
||||
archetype: corePersona?.archetype,
|
||||
platform: platform,
|
||||
linguistic_fingerprint: corePersona?.linguistic_fingerprint,
|
||||
platform_constraints: platformPersona?.content_format_rules,
|
||||
engagement_patterns: platformPersona?.engagement_patterns
|
||||
}
|
||||
},
|
||||
categories: ["complete-persona", platform, "writing-guidance"],
|
||||
parentId: corePersona?.id?.toString()
|
||||
});
|
||||
|
||||
// Loading state
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-4">
|
||||
<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...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Error state
|
||||
if (error && !corePersona) {
|
||||
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">Failed to load persona data</h3>
|
||||
<p className="text-sm text-red-700 mt-1">{error}</p>
|
||||
<button
|
||||
onClick={refreshPersonas}
|
||||
className="mt-2 text-sm text-red-600 hover:text-red-500 underline"
|
||||
>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Success state - provide context
|
||||
return (
|
||||
<PlatformPersonaContext.Provider value={{
|
||||
corePersona,
|
||||
platformPersona,
|
||||
platform,
|
||||
loading,
|
||||
error,
|
||||
refreshPersonas
|
||||
}}>
|
||||
{children}
|
||||
</PlatformPersonaContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// Custom hook to use the context
|
||||
export const usePlatformPersonaContext = () => {
|
||||
const context = useContext(PlatformPersonaContext);
|
||||
if (!context) {
|
||||
throw new Error('usePlatformPersonaContext must be used within PlatformPersonaProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
// Export the context for direct access if needed
|
||||
export { PlatformPersonaContext };
|
||||
19
frontend/src/components/shared/PersonaContext/index.ts
Normal file
19
frontend/src/components/shared/PersonaContext/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Persona Context Index
|
||||
* Central export point for all persona context components and hooks
|
||||
*/
|
||||
|
||||
export {
|
||||
PlatformPersonaProvider,
|
||||
PlatformPersonaContext,
|
||||
usePlatformPersonaContext
|
||||
} from './PlatformPersonaProvider';
|
||||
|
||||
export { PersonaTestComponent } from './PersonaTestComponent';
|
||||
|
||||
// Re-export types for convenience
|
||||
export type {
|
||||
PlatformType,
|
||||
WritingPersona,
|
||||
PlatformAdaptation
|
||||
} from '../../../types/PlatformPersonaTypes';
|
||||
13
frontend/src/hooks/usePlatformPersonaContext.ts
Normal file
13
frontend/src/hooks/usePlatformPersonaContext.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* usePlatformPersonaContext Hook
|
||||
* Custom hook for accessing platform-specific persona context
|
||||
* Re-exports the hook from PlatformPersonaProvider for better organization
|
||||
*/
|
||||
|
||||
export { usePlatformPersonaContext } from '../components/shared/PersonaContext/PlatformPersonaProvider';
|
||||
|
||||
// Additional utility hooks can be added here in the future
|
||||
// For example:
|
||||
// - usePersonaValidation
|
||||
// - usePersonaOptimization
|
||||
// - usePersonaAnalytics
|
||||
310
frontend/src/types/PlatformPersonaTypes.ts
Normal file
310
frontend/src/types/PlatformPersonaTypes.ts
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* Platform Persona Types
|
||||
* TypeScript interfaces mapping to backend persona models from PR #226
|
||||
*/
|
||||
|
||||
// Core Writing Persona Interface
|
||||
export interface WritingPersona {
|
||||
id: number;
|
||||
user_id: number;
|
||||
persona_name: string;
|
||||
archetype: string;
|
||||
core_belief: string;
|
||||
brand_voice_description: string;
|
||||
linguistic_fingerprint: LinguisticFingerprint;
|
||||
platform_adaptations: PlatformAdaptation[];
|
||||
onboarding_session_id: number;
|
||||
source_website_analysis: any;
|
||||
source_research_preferences: any;
|
||||
ai_analysis_version: string;
|
||||
confidence_score: number;
|
||||
analysis_date: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
// Linguistic Fingerprint Interface
|
||||
export interface LinguisticFingerprint {
|
||||
sentence_metrics: SentenceMetrics;
|
||||
lexical_features: LexicalFeatures;
|
||||
rhetorical_devices: RhetoricalDevices;
|
||||
}
|
||||
|
||||
// Sentence Metrics Interface
|
||||
export interface SentenceMetrics {
|
||||
average_sentence_length_words: number;
|
||||
preferred_sentence_type: string;
|
||||
active_to_passive_ratio: string;
|
||||
sentence_complexity: string;
|
||||
paragraph_structure: string;
|
||||
}
|
||||
|
||||
// Lexical Features Interface
|
||||
export interface LexicalFeatures {
|
||||
go_to_words: string[];
|
||||
go_to_phrases: string[];
|
||||
avoid_words: string[];
|
||||
contractions: string;
|
||||
vocabulary_level: string;
|
||||
industry_terminology: string[];
|
||||
emotional_tone_words: string[];
|
||||
}
|
||||
|
||||
// Rhetorical Devices Interface
|
||||
export interface RhetoricalDevices {
|
||||
metaphors: string;
|
||||
analogies: string;
|
||||
rhetorical_questions: string;
|
||||
storytelling_approach: string;
|
||||
persuasion_techniques: string[];
|
||||
}
|
||||
|
||||
// Platform Types
|
||||
export type PlatformType =
|
||||
| "twitter"
|
||||
| "linkedin"
|
||||
| "instagram"
|
||||
| "facebook"
|
||||
| "blog"
|
||||
| "medium"
|
||||
| "substack";
|
||||
|
||||
// Platform Adaptation Interface
|
||||
export interface PlatformAdaptation {
|
||||
id: number;
|
||||
writing_persona_id: number;
|
||||
platform_type: PlatformType;
|
||||
sentence_metrics: PlatformSentenceMetrics;
|
||||
lexical_features: PlatformLexicalFeatures;
|
||||
rhetorical_devices: PlatformRhetoricalDevices;
|
||||
tonal_range: TonalRange;
|
||||
stylistic_constraints: StylisticConstraints;
|
||||
content_format_rules: ContentFormatRules;
|
||||
engagement_patterns: EngagementPatterns;
|
||||
posting_frequency: PostingFrequency;
|
||||
content_types: ContentTypes;
|
||||
platform_best_practices: PlatformBestPractices;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// Platform-Specific Sentence Metrics
|
||||
export interface PlatformSentenceMetrics {
|
||||
optimal_length: string;
|
||||
character_limit: number;
|
||||
sentence_structure: string;
|
||||
paragraph_breaks: string;
|
||||
readability_score: number;
|
||||
}
|
||||
|
||||
// Platform-Specific Lexical Features
|
||||
export interface PlatformLexicalFeatures {
|
||||
hashtag_strategy: string;
|
||||
platform_specific_terms: string[];
|
||||
engagement_phrases: string[];
|
||||
call_to_action_style: string;
|
||||
}
|
||||
|
||||
// Platform-Specific Rhetorical Devices
|
||||
export interface PlatformRhetoricalDevices {
|
||||
question_frequency: string;
|
||||
story_elements: string;
|
||||
visual_descriptions: string;
|
||||
interactive_elements: string;
|
||||
}
|
||||
|
||||
// Tonal Range Interface
|
||||
export interface TonalRange {
|
||||
default_tone: string;
|
||||
permissible_tones: string[];
|
||||
forbidden_tones: string[];
|
||||
emotional_range: string;
|
||||
formality_level: string;
|
||||
}
|
||||
|
||||
// Stylistic Constraints Interface
|
||||
export interface StylisticConstraints {
|
||||
punctuation_preferences: string;
|
||||
formatting_rules: string;
|
||||
emoji_usage: string;
|
||||
link_placement: string;
|
||||
media_integration: string;
|
||||
}
|
||||
|
||||
// Content Format Rules Interface
|
||||
export interface ContentFormatRules {
|
||||
character_limit: number;
|
||||
optimal_length: string;
|
||||
word_count: string;
|
||||
hashtag_limit: number;
|
||||
media_requirements: string;
|
||||
link_restrictions: string;
|
||||
}
|
||||
|
||||
// Engagement Patterns Interface
|
||||
export interface EngagementPatterns {
|
||||
posting_frequency: string;
|
||||
best_timing: string;
|
||||
interaction_style: string;
|
||||
response_strategy: string;
|
||||
community_approach: string;
|
||||
}
|
||||
|
||||
// Posting Frequency Interface
|
||||
export interface PostingFrequency {
|
||||
frequency: string;
|
||||
optimal_days: string[];
|
||||
optimal_times: string[];
|
||||
seasonal_adjustments: string;
|
||||
}
|
||||
|
||||
// Content Types Interface
|
||||
export interface ContentTypes {
|
||||
primary_content: string[];
|
||||
secondary_content: string[];
|
||||
content_mix: string;
|
||||
seasonal_content: string[];
|
||||
}
|
||||
|
||||
// Platform Best Practices Interface
|
||||
export interface PlatformBestPractices {
|
||||
algorithm_tips: string[];
|
||||
engagement_tactics: string[];
|
||||
content_strategies: string[];
|
||||
growth_hacks: string[];
|
||||
}
|
||||
|
||||
// Persona Analysis Result Interface
|
||||
export interface PersonaAnalysisResult {
|
||||
id: number;
|
||||
writing_persona_id: number;
|
||||
analysis_prompt: string;
|
||||
linguistic_analysis: any;
|
||||
platform_recommendations: any;
|
||||
confidence_score: number;
|
||||
analysis_date: string;
|
||||
ai_model_version: string;
|
||||
}
|
||||
|
||||
// Persona Validation Result Interface
|
||||
export interface PersonaValidationResult {
|
||||
id: number;
|
||||
writing_persona_id: number;
|
||||
stylometric_accuracy: number;
|
||||
consistency_score: number;
|
||||
platform_compliance: number;
|
||||
user_satisfaction: number;
|
||||
validation_date: string;
|
||||
improvement_suggestions: string[];
|
||||
}
|
||||
|
||||
// API Response Interfaces
|
||||
export interface PersonaGenerationResponse {
|
||||
success: boolean;
|
||||
persona_id?: number;
|
||||
message: string;
|
||||
confidence_score?: number;
|
||||
data_sufficiency?: number;
|
||||
platforms_generated?: string[];
|
||||
}
|
||||
|
||||
export interface PersonaReadinessResponse {
|
||||
ready: boolean;
|
||||
message: string;
|
||||
missing_steps: string[];
|
||||
data_sufficiency: number;
|
||||
recommendations?: string[];
|
||||
}
|
||||
|
||||
export interface PersonaPreviewResponse {
|
||||
preview: {
|
||||
identity: {
|
||||
persona_name: string;
|
||||
archetype: string;
|
||||
core_belief: string;
|
||||
brand_voice_description: string;
|
||||
};
|
||||
linguistic_fingerprint: any;
|
||||
tonal_range: any;
|
||||
sample_platform: {
|
||||
platform: string;
|
||||
adaptation: any;
|
||||
};
|
||||
};
|
||||
confidence_score: number;
|
||||
data_sufficiency: number;
|
||||
}
|
||||
|
||||
// Platform Information Interface
|
||||
export interface PlatformInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
character_limit?: number;
|
||||
optimal_length?: string;
|
||||
word_count?: string;
|
||||
seo_optimized?: boolean;
|
||||
storytelling_focus?: boolean;
|
||||
subscription_focus?: boolean;
|
||||
}
|
||||
|
||||
// Supported Platforms Response Interface
|
||||
export interface SupportedPlatformsResponse {
|
||||
platforms: PlatformInfo[];
|
||||
}
|
||||
|
||||
// User Personas Response Interface
|
||||
export interface UserPersonasResponse {
|
||||
personas: WritingPersona[];
|
||||
total_count: number;
|
||||
active_count: number;
|
||||
}
|
||||
|
||||
// Platform Persona Response Interface
|
||||
export interface PlatformPersonaResponse {
|
||||
platform_type: PlatformType;
|
||||
sentence_metrics: PlatformSentenceMetrics;
|
||||
lexical_features: PlatformLexicalFeatures;
|
||||
content_format_rules: ContentFormatRules;
|
||||
engagement_patterns: EngagementPatterns;
|
||||
platform_best_practices: PlatformBestPractices;
|
||||
}
|
||||
|
||||
// Content Generation Request Interface
|
||||
export interface ContentGenerationRequest {
|
||||
platform: PlatformType;
|
||||
topic: string;
|
||||
content_type: string;
|
||||
additional_context?: string;
|
||||
}
|
||||
|
||||
// Content Generation Response Interface
|
||||
export interface ContentGenerationResponse {
|
||||
success: boolean;
|
||||
content: string;
|
||||
metadata: {
|
||||
character_count: number;
|
||||
word_count: number;
|
||||
persona_compliance_score: number;
|
||||
platform_optimization_score: number;
|
||||
generated_at: string;
|
||||
};
|
||||
suggestions?: string[];
|
||||
}
|
||||
|
||||
// Export Persona Request Interface
|
||||
export interface ExportPersonaRequest {
|
||||
platform: PlatformType;
|
||||
format: "prompt" | "json" | "markdown";
|
||||
include_metadata?: boolean;
|
||||
}
|
||||
|
||||
// Export Persona Response Interface
|
||||
export interface ExportPersonaResponse {
|
||||
success: boolean;
|
||||
content: string;
|
||||
format: string;
|
||||
export_date: string;
|
||||
version: string;
|
||||
}
|
||||
Reference in New Issue
Block a user