1018 lines
34 KiB
Markdown
1018 lines
34 KiB
Markdown
# CopilotKit Technical Specification
|
|
## ALwrity Strategy Builder Integration
|
|
|
|
---
|
|
|
|
## 📋 **Overview**
|
|
|
|
This document provides detailed technical specifications for integrating CopilotKit into ALwrity's Content Strategy Builder. It includes specific code changes, file modifications, and implementation details.
|
|
|
|
---
|
|
|
|
## 🏗️ **Architecture Changes**
|
|
|
|
### **Current Architecture**
|
|
```
|
|
ALwrityApp
|
|
├── ContentPlanningDashboard
|
|
│ ├── ContentStrategyBuilder
|
|
│ │ ├── StrategicInputField
|
|
│ │ ├── CategoryList
|
|
│ │ └── ActionButtons
|
|
│ └── StrategyOnboardingDialog
|
|
└── Stores
|
|
├── strategyBuilderStore
|
|
└── enhancedStrategyStore
|
|
```
|
|
|
|
### **New Architecture with CopilotKit**
|
|
```
|
|
ALwrityApp
|
|
├── CopilotKit Provider (Cloud-based)
|
|
│ ├── CopilotSidebar
|
|
│ └── CopilotContext
|
|
├── ContentPlanningDashboard
|
|
│ ├── ContentStrategyBuilder
|
|
│ │ ├── StrategicInputField
|
|
│ │ ├── CategoryList
|
|
│ │ ├── ActionButtons
|
|
│ │ └── CopilotActions (NEW)
|
|
│ └── StrategyOnboardingDialog
|
|
├── Stores
|
|
│ ├── strategyBuilderStore
|
|
│ ├── enhancedStrategyStore
|
|
│ └── copilotStore (NEW)
|
|
└── Services
|
|
├── copilotKitService (NEW)
|
|
└── strategyAIService (NEW)
|
|
```
|
|
|
|
---
|
|
|
|
## 📁 **File Modifications**
|
|
|
|
### **1. App-Level Integration**
|
|
|
|
#### **File: `frontend/src/App.tsx`**
|
|
```typescript
|
|
// ADD: CopilotKit imports
|
|
import { CopilotKit } from "@copilotkit/react-core";
|
|
import { CopilotSidebar } from "@copilotkit/react-ui";
|
|
import "@copilotkit/react-ui/styles.css";
|
|
|
|
// MODIFY: App component
|
|
function App() {
|
|
return (
|
|
<CopilotKit
|
|
publicApiKey={process.env.REACT_APP_COPILOTKIT_API_KEY || "demo"}
|
|
>
|
|
<CopilotSidebar
|
|
labels={{
|
|
title: "ALwrity Strategy Assistant",
|
|
initial: "Hi! I'm here to help you build your content strategy. I can auto-populate fields, provide guidance, and ensure your strategy is comprehensive. What would you like to start with?"
|
|
}}
|
|
observabilityHooks={{
|
|
onChatExpanded: () => analytics.track("strategy_assistant_opened"),
|
|
onMessageSent: (message) => analytics.track("strategy_message_sent", { message }),
|
|
onFeedbackGiven: (messageId, type) => analytics.track("strategy_feedback", { messageId, type })
|
|
}}
|
|
>
|
|
<Router>
|
|
{/* Existing app content */}
|
|
</Router>
|
|
</CopilotSidebar>
|
|
</CopilotKit>
|
|
);
|
|
}
|
|
```
|
|
|
|
**Key Changes:**
|
|
- Uses only `publicApiKey` (no `runtimeUrl` needed)
|
|
- CopilotKit runs on cloud infrastructure
|
|
- Actions communicate with ALwrity's custom backend endpoints
|
|
|
|
### **2. Strategy Builder Integration**
|
|
|
|
#### **File: `frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder.tsx`**
|
|
```typescript
|
|
// ADD: CopilotKit imports
|
|
import { useCopilotAction, useCopilotReadable, useCopilotAdditionalInstructions } from "@copilotkit/react-core";
|
|
|
|
// ADD: CopilotKit hooks
|
|
const ContentStrategyBuilder: React.FC = () => {
|
|
// Existing store hooks...
|
|
|
|
// ADD: CopilotKit context provision
|
|
useCopilotReadable({
|
|
description: "Current strategy form state and field data",
|
|
value: {
|
|
formData,
|
|
completionPercentage: calculateCompletionPercentage(),
|
|
filledFields: Object.keys(formData).filter(key => formData[key]),
|
|
emptyFields: Object.keys(formData).filter(key => !formData[key]),
|
|
categoryProgress: getCompletionStats().category_completion,
|
|
activeCategory,
|
|
formErrors
|
|
}
|
|
});
|
|
|
|
// ADD: Field definitions context
|
|
useCopilotReadable({
|
|
description: "Strategy field definitions and requirements",
|
|
value: STRATEGIC_INPUT_FIELDS.map(field => ({
|
|
id: field.id,
|
|
label: field.label,
|
|
description: field.description,
|
|
tooltip: field.tooltip,
|
|
required: field.required,
|
|
type: field.type,
|
|
options: field.options,
|
|
category: field.category
|
|
}))
|
|
});
|
|
|
|
// ADD: Onboarding data context
|
|
useCopilotReadable({
|
|
description: "User onboarding data for personalization",
|
|
value: {
|
|
websiteAnalysis: personalizationData?.website_analysis,
|
|
researchPreferences: personalizationData?.research_preferences,
|
|
apiKeys: personalizationData?.api_keys,
|
|
userProfile: personalizationData?.user_profile
|
|
}
|
|
});
|
|
|
|
// ADD: Dynamic instructions
|
|
useCopilotAdditionalInstructions({
|
|
instructions: `
|
|
You are ALwrity's Strategy Assistant, helping users create comprehensive content strategies.
|
|
|
|
Current context:
|
|
- Form completion: ${calculateCompletionPercentage()}%
|
|
- Active category: ${activeCategory}
|
|
- Filled fields: ${Object.keys(formData).filter(k => formData[k]).length}/30
|
|
|
|
Guidelines:
|
|
- Always reference real onboarding data when available
|
|
- Provide specific, actionable suggestions
|
|
- Explain the reasoning behind recommendations
|
|
- Help users understand field relationships
|
|
- Suggest next steps based on current progress
|
|
- Use actual database data, never mock data
|
|
`
|
|
});
|
|
|
|
// Existing component logic...
|
|
};
|
|
```
|
|
|
|
### **3. CopilotKit Actions Implementation**
|
|
|
|
#### **File: `frontend/src/components/ContentPlanningDashboard/components/ContentStrategyBuilder/CopilotActions.tsx` (NEW)**
|
|
```typescript
|
|
import { useCopilotAction } from "@copilotkit/react-core";
|
|
import { useStrategyBuilderStore } from "../../../../stores/strategyBuilderStore";
|
|
import { strategyAIService } from "../../../../services/strategyAIService";
|
|
|
|
export const useCopilotActions = () => {
|
|
const {
|
|
formData,
|
|
updateFormField,
|
|
validateFormField,
|
|
setError,
|
|
autoPopulatedFields,
|
|
dataSources
|
|
} = useStrategyBuilderStore();
|
|
|
|
// Action 1: Populate individual field
|
|
useCopilotAction({
|
|
name: "populateStrategyField",
|
|
description: "Intelligently populate a strategy field with contextual data",
|
|
parameters: [
|
|
{ name: "fieldId", type: "string", required: true },
|
|
{ name: "value", type: "string", required: true },
|
|
{ name: "reasoning", type: "string", required: false },
|
|
{ name: "dataSource", type: "string", required: false }
|
|
],
|
|
handler: async ({ fieldId, value, reasoning, dataSource }) => {
|
|
try {
|
|
// Update form field
|
|
updateFormField(fieldId, value);
|
|
|
|
// Show reasoning to user
|
|
if (reasoning) {
|
|
showNotification(`Filled ${fieldId}: ${reasoning}`);
|
|
}
|
|
|
|
// Track data source
|
|
if (dataSource) {
|
|
updateDataSource(fieldId, dataSource);
|
|
}
|
|
|
|
return { success: true, message: `Field ${fieldId} populated successfully` };
|
|
} catch (error) {
|
|
setError(`Failed to populate field ${fieldId}: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
|
|
// Action 2: Bulk populate category
|
|
useCopilotAction({
|
|
name: "populateStrategyCategory",
|
|
description: "Populate all fields in a specific category based on user description",
|
|
parameters: [
|
|
{ name: "category", type: "string", required: true },
|
|
{ name: "userDescription", type: "string", required: true }
|
|
],
|
|
handler: async ({ category, userDescription }) => {
|
|
try {
|
|
const populatedData = await strategyAIService.generateCategoryData(category, userDescription, formData);
|
|
|
|
// Update all fields in category
|
|
Object.entries(populatedData).forEach(([fieldId, value]) => {
|
|
updateFormField(fieldId, value);
|
|
});
|
|
|
|
showNotification(`Populated ${category} fields based on your description`);
|
|
return { success: true, message: `Category ${category} populated successfully` };
|
|
} catch (error) {
|
|
setError(`Failed to populate category ${category}: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
|
|
// Action 3: Validate field
|
|
useCopilotAction({
|
|
name: "validateStrategyField",
|
|
description: "Validate a strategy field and provide improvement suggestions",
|
|
parameters: [
|
|
{ name: "fieldId", type: "string", required: true }
|
|
],
|
|
handler: async ({ fieldId }) => {
|
|
try {
|
|
const validation = await strategyAIService.validateField(fieldId, formData[fieldId]);
|
|
|
|
if (validation.isValid) {
|
|
showSuccess(`✅ ${fieldId} looks good!`);
|
|
} else {
|
|
showWarning(`⚠️ ${fieldId}: ${validation.suggestion}`);
|
|
}
|
|
|
|
return { success: true, validation };
|
|
} catch (error) {
|
|
setError(`Failed to validate field ${fieldId}: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
|
|
// Action 4: Review strategy
|
|
useCopilotAction({
|
|
name: "reviewStrategy",
|
|
description: "Comprehensive strategy review with AI analysis",
|
|
handler: async () => {
|
|
try {
|
|
const review = await strategyAIService.analyzeStrategy(formData);
|
|
return { success: true, review };
|
|
} catch (error) {
|
|
setError(`Failed to review strategy: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
|
|
// Action 5: Generate suggestions
|
|
useCopilotAction({
|
|
name: "generateSuggestions",
|
|
description: "Generate contextual suggestions for incomplete fields",
|
|
parameters: [
|
|
{ name: "fieldId", type: "string", required: true }
|
|
],
|
|
handler: async ({ fieldId }) => {
|
|
try {
|
|
const suggestions = await strategyAIService.generateFieldSuggestions(fieldId, formData);
|
|
return { success: true, suggestions };
|
|
} catch (error) {
|
|
setError(`Failed to generate suggestions: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
|
|
// Action 6: Auto-populate from onboarding
|
|
useCopilotAction({
|
|
name: "autoPopulateFromOnboarding",
|
|
description: "Auto-populate strategy fields using onboarding data",
|
|
handler: async () => {
|
|
try {
|
|
await autoPopulateFromOnboarding();
|
|
showNotification("Strategy fields populated from your onboarding data");
|
|
return { success: true, message: "Auto-population completed" };
|
|
} catch (error) {
|
|
setError(`Failed to auto-populate: ${error.message}`);
|
|
return { success: false, message: error.message };
|
|
}
|
|
}
|
|
});
|
|
};
|
|
```
|
|
|
|
### **4. New Services**
|
|
|
|
#### **File: `frontend/src/services/strategyAIService.ts` (NEW)**
|
|
```typescript
|
|
import { apiClient } from '../api/client';
|
|
|
|
export interface FieldValidation {
|
|
isValid: boolean;
|
|
suggestion?: string;
|
|
confidence: number;
|
|
}
|
|
|
|
export interface StrategyReview {
|
|
completeness: number;
|
|
coherence: number;
|
|
alignment: number;
|
|
suggestions: string[];
|
|
missingFields: string[];
|
|
improvements: string[];
|
|
}
|
|
|
|
export interface FieldSuggestions {
|
|
suggestions: string[];
|
|
reasoning: string;
|
|
confidence: number;
|
|
}
|
|
|
|
export const strategyAIService = {
|
|
/**
|
|
* Generate data for a specific category
|
|
*/
|
|
async generateCategoryData(category: string, userDescription: string, currentFormData: any): Promise<Record<string, any>> {
|
|
try {
|
|
const response = await apiClient.post('/api/content-planning/strategy/generate-category-data', {
|
|
category,
|
|
userDescription,
|
|
currentFormData
|
|
});
|
|
return response.data.data;
|
|
} catch (error: any) {
|
|
throw new Error(error.response?.data?.detail || 'Failed to generate category data');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Validate a specific field
|
|
*/
|
|
async validateField(fieldId: string, value: any): Promise<FieldValidation> {
|
|
try {
|
|
const response = await apiClient.post('/api/content-planning/strategy/validate-field', {
|
|
fieldId,
|
|
value
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
throw new Error(error.response?.data?.detail || 'Failed to validate field');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Analyze complete strategy
|
|
*/
|
|
async analyzeStrategy(formData: any): Promise<StrategyReview> {
|
|
try {
|
|
const response = await apiClient.post('/api/content-planning/strategy/analyze', {
|
|
formData
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
throw new Error(error.response?.data?.detail || 'Failed to analyze strategy');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Generate suggestions for a field
|
|
*/
|
|
async generateFieldSuggestions(fieldId: string, currentFormData: any): Promise<FieldSuggestions> {
|
|
try {
|
|
const response = await apiClient.post('/api/content-planning/strategy/generate-suggestions', {
|
|
fieldId,
|
|
currentFormData
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
throw new Error(error.response?.data?.detail || 'Failed to generate suggestions');
|
|
}
|
|
}
|
|
};
|
|
```
|
|
|
|
### **5. Backend API Endpoints**
|
|
|
|
#### **File: `backend/api/content_planning/strategy_copilot.py` (NEW)**
|
|
```python
|
|
from fastapi import APIRouter, HTTPException, Depends
|
|
from sqlalchemy.orm import Session
|
|
from typing import Dict, Any, List
|
|
from services.database import get_db
|
|
from services.strategy_copilot_service import StrategyCopilotService
|
|
|
|
router = APIRouter(prefix="/api/content-planning/strategy", tags=["strategy-copilot"])
|
|
|
|
@router.post("/generate-category-data")
|
|
async def generate_category_data(
|
|
request: Dict[str, Any],
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Generate data for a specific category based on user description."""
|
|
try:
|
|
service = StrategyCopilotService(db)
|
|
result = await service.generate_category_data(
|
|
category=request["category"],
|
|
user_description=request["userDescription"],
|
|
current_form_data=request["currentFormData"]
|
|
)
|
|
return {"success": True, "data": result}
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
@router.post("/validate-field")
|
|
async def validate_field(
|
|
request: Dict[str, Any],
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Validate a specific strategy field."""
|
|
try:
|
|
service = StrategyCopilotService(db)
|
|
result = await service.validate_field(
|
|
field_id=request["fieldId"],
|
|
value=request["value"]
|
|
)
|
|
return result
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
@router.post("/analyze")
|
|
async def analyze_strategy(
|
|
request: Dict[str, Any],
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Analyze complete strategy for completeness and coherence."""
|
|
try:
|
|
service = StrategyCopilotService(db)
|
|
result = await service.analyze_strategy(
|
|
form_data=request["formData"]
|
|
)
|
|
return result
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
@router.post("/generate-suggestions")
|
|
async def generate_suggestions(
|
|
request: Dict[str, Any],
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Generate suggestions for a specific field."""
|
|
try:
|
|
service = StrategyCopilotService(db)
|
|
result = await service.generate_field_suggestions(
|
|
field_id=request["fieldId"],
|
|
current_form_data=request["currentFormData"]
|
|
)
|
|
return result
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
```
|
|
|
|
### **6. Backend Service**
|
|
|
|
#### **File: `backend/services/strategy_copilot_service.py` (NEW)**
|
|
```python
|
|
from typing import Dict, Any, List, Optional
|
|
from sqlalchemy.orm import Session
|
|
from loguru import logger
|
|
from services.onboarding_data_service import OnboardingDataService
|
|
from services.user_data_service import UserDataService
|
|
from services.llm_providers.google_genai_provider import GoogleGenAIProvider
|
|
|
|
class StrategyCopilotService:
|
|
"""Service for CopilotKit strategy assistance using Gemini."""
|
|
|
|
def __init__(self, db: Session):
|
|
self.db = db
|
|
self.onboarding_service = OnboardingDataService()
|
|
self.user_data_service = UserDataService(db)
|
|
self.llm_provider = GoogleGenAIProvider()
|
|
|
|
async def generate_category_data(
|
|
self,
|
|
category: str,
|
|
user_description: str,
|
|
current_form_data: Dict[str, Any]
|
|
) -> Dict[str, Any]:
|
|
"""Generate data for a specific category."""
|
|
try:
|
|
# Get user onboarding data
|
|
user_id = 1 # TODO: Get from auth context
|
|
onboarding_data = self.onboarding_service.get_personalized_ai_inputs(user_id)
|
|
|
|
# Build prompt for category generation
|
|
prompt = self._build_category_generation_prompt(
|
|
category, user_description, current_form_data, onboarding_data
|
|
)
|
|
|
|
# Generate response using Gemini
|
|
response = await self.llm_provider.generate_text(prompt)
|
|
|
|
# Parse and validate response
|
|
generated_data = self._parse_category_response(response, category)
|
|
|
|
return generated_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating category data: {str(e)}")
|
|
raise
|
|
|
|
async def validate_field(self, field_id: str, value: Any) -> Dict[str, Any]:
|
|
"""Validate a specific strategy field."""
|
|
try:
|
|
# Get field definition
|
|
field_definition = self._get_field_definition(field_id)
|
|
|
|
# Build validation prompt
|
|
prompt = self._build_validation_prompt(field_definition, value)
|
|
|
|
# Generate validation response using Gemini
|
|
response = await self.llm_provider.generate_text(prompt)
|
|
|
|
# Parse validation result
|
|
validation_result = self._parse_validation_response(response)
|
|
|
|
return validation_result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error validating field {field_id}: {str(e)}")
|
|
raise
|
|
|
|
async def analyze_strategy(self, form_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Analyze complete strategy for completeness and coherence."""
|
|
try:
|
|
# Get user data for context
|
|
user_id = 1 # TODO: Get from auth context
|
|
onboarding_data = self.onboarding_service.get_personalized_ai_inputs(user_id)
|
|
|
|
# Build analysis prompt
|
|
prompt = self._build_analysis_prompt(form_data, onboarding_data)
|
|
|
|
# Generate analysis using Gemini
|
|
response = await self.llm_provider.generate_text(prompt)
|
|
|
|
# Parse analysis result
|
|
analysis_result = self._parse_analysis_response(response)
|
|
|
|
return analysis_result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error analyzing strategy: {str(e)}")
|
|
raise
|
|
|
|
async def generate_field_suggestions(
|
|
self,
|
|
field_id: str,
|
|
current_form_data: Dict[str, Any]
|
|
) -> Dict[str, Any]:
|
|
"""Generate suggestions for a specific field."""
|
|
try:
|
|
# Get field definition
|
|
field_definition = self._get_field_definition(field_id)
|
|
|
|
# Get user data
|
|
user_id = 1 # TODO: Get from auth context
|
|
onboarding_data = self.onboarding_service.get_personalized_ai_inputs(user_id)
|
|
|
|
# Build suggestions prompt
|
|
prompt = self._build_suggestions_prompt(
|
|
field_definition, current_form_data, onboarding_data
|
|
)
|
|
|
|
# Generate suggestions using Gemini
|
|
response = await self.llm_provider.generate_text(prompt)
|
|
|
|
# Parse suggestions
|
|
suggestions = self._parse_suggestions_response(response)
|
|
|
|
return suggestions
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error generating suggestions for {field_id}: {str(e)}")
|
|
raise
|
|
|
|
def _build_category_generation_prompt(
|
|
self,
|
|
category: str,
|
|
user_description: str,
|
|
current_form_data: Dict[str, Any],
|
|
onboarding_data: Dict[str, Any]
|
|
) -> str:
|
|
"""Build prompt for category data generation."""
|
|
return f"""
|
|
You are ALwrity's Strategy Assistant. Generate data for the {category} category based on the user's description.
|
|
|
|
User Description: {user_description}
|
|
|
|
Current Form Data: {current_form_data}
|
|
|
|
Onboarding Data: {onboarding_data}
|
|
|
|
Category Fields: {self._get_category_fields(category)}
|
|
|
|
Generate appropriate values for all fields in the {category} category. Return only valid JSON with field IDs as keys.
|
|
|
|
Example response format:
|
|
{{
|
|
"field_id": "value",
|
|
"another_field": "value"
|
|
}}
|
|
"""
|
|
|
|
def _build_validation_prompt(self, field_definition: Dict[str, Any], value: Any) -> str:
|
|
"""Build prompt for field validation."""
|
|
return f"""
|
|
Validate the following field value:
|
|
|
|
Field: {field_definition['label']}
|
|
Description: {field_definition['description']}
|
|
Required: {field_definition['required']}
|
|
Type: {field_definition['type']}
|
|
Value: {value}
|
|
|
|
Return JSON with: {{"isValid": boolean, "suggestion": string, "confidence": number}}
|
|
|
|
Example response:
|
|
{{
|
|
"isValid": true,
|
|
"suggestion": "This looks good!",
|
|
"confidence": 0.95
|
|
}}
|
|
"""
|
|
|
|
def _build_analysis_prompt(
|
|
self,
|
|
form_data: Dict[str, Any],
|
|
onboarding_data: Dict[str, Any]
|
|
) -> str:
|
|
"""Build prompt for strategy analysis."""
|
|
return f"""
|
|
Analyze the following content strategy for completeness, coherence, and alignment:
|
|
|
|
Form Data: {form_data}
|
|
Onboarding Data: {onboarding_data}
|
|
|
|
Return JSON with: {{
|
|
"completeness": number,
|
|
"coherence": number,
|
|
"alignment": number,
|
|
"suggestions": [string],
|
|
"missingFields": [string],
|
|
"improvements": [string]
|
|
}}
|
|
|
|
Example response:
|
|
{{
|
|
"completeness": 85,
|
|
"coherence": 90,
|
|
"alignment": 88,
|
|
"suggestions": ["Consider adding more specific metrics"],
|
|
"missingFields": ["content_budget"],
|
|
"improvements": ["Add timeline details"]
|
|
}}
|
|
"""
|
|
|
|
def _build_suggestions_prompt(
|
|
self,
|
|
field_definition: Dict[str, Any],
|
|
current_form_data: Dict[str, Any],
|
|
onboarding_data: Dict[str, Any]
|
|
) -> str:
|
|
"""Build prompt for field suggestions."""
|
|
return f"""
|
|
Generate suggestions for the following field:
|
|
|
|
Field: {field_definition['label']}
|
|
Description: {field_definition['description']}
|
|
Required: {field_definition['required']}
|
|
Type: {field_definition['type']}
|
|
|
|
Current Form Data: {current_form_data}
|
|
Onboarding Data: {onboarding_data}
|
|
|
|
Return JSON with: {{
|
|
"suggestions": [string],
|
|
"reasoning": string,
|
|
"confidence": number
|
|
}}
|
|
|
|
Example response:
|
|
{{
|
|
"suggestions": ["Focus on measurable outcomes", "Align with business goals"],
|
|
"reasoning": "Based on your business context, measurable outcomes will be most effective",
|
|
"confidence": 0.92
|
|
}}
|
|
"""
|
|
|
|
def _get_field_definition(self, field_id: str) -> Dict[str, Any]:
|
|
"""Get field definition from STRATEGIC_INPUT_FIELDS."""
|
|
# This would be imported from the frontend field definitions
|
|
# For now, return a basic structure
|
|
return {
|
|
"id": field_id,
|
|
"label": field_id.replace("_", " ").title(),
|
|
"description": f"Description for {field_id}",
|
|
"required": True,
|
|
"type": "text"
|
|
}
|
|
|
|
def _get_category_fields(self, category: str) -> List[str]:
|
|
"""Get fields for a specific category."""
|
|
# This would be imported from the frontend field definitions
|
|
category_fields = {
|
|
"business_context": [
|
|
"business_objectives", "target_metrics", "content_budget", "team_size",
|
|
"implementation_timeline", "market_share", "competitive_position", "performance_metrics"
|
|
],
|
|
"audience_intelligence": [
|
|
"content_preferences", "consumption_patterns", "audience_pain_points",
|
|
"buying_journey", "seasonal_trends", "engagement_metrics"
|
|
],
|
|
"competitive_intelligence": [
|
|
"top_competitors", "competitor_content_strategies", "market_gaps",
|
|
"industry_trends", "emerging_trends"
|
|
],
|
|
"content_strategy": [
|
|
"preferred_formats", "content_mix", "content_frequency", "optimal_timing",
|
|
"quality_metrics", "editorial_guidelines", "brand_voice"
|
|
],
|
|
"performance_analytics": [
|
|
"traffic_sources", "conversion_rates", "content_roi_targets", "ab_testing_capabilities"
|
|
]
|
|
}
|
|
return category_fields.get(category, [])
|
|
|
|
def _parse_category_response(self, response: str, category: str) -> Dict[str, Any]:
|
|
"""Parse LLM response for category data."""
|
|
try:
|
|
import json
|
|
# Clean up the response to extract JSON
|
|
response = response.strip()
|
|
if response.startswith("```json"):
|
|
response = response[7:]
|
|
if response.endswith("```"):
|
|
response = response[:-3]
|
|
response = response.strip()
|
|
|
|
return json.loads(response)
|
|
except Exception as e:
|
|
logger.error(f"Error parsing category response: {str(e)}")
|
|
return {}
|
|
|
|
def _parse_validation_response(self, response: str) -> Dict[str, Any]:
|
|
"""Parse LLM response for validation."""
|
|
try:
|
|
import json
|
|
# Clean up the response to extract JSON
|
|
response = response.strip()
|
|
if response.startswith("```json"):
|
|
response = response[7:]
|
|
if response.endswith("```"):
|
|
response = response[:-3]
|
|
response = response.strip()
|
|
|
|
return json.loads(response)
|
|
except Exception as e:
|
|
logger.error(f"Error parsing validation response: {str(e)}")
|
|
return {"isValid": False, "suggestion": "Unable to validate", "confidence": 0}
|
|
|
|
def _parse_analysis_response(self, response: str) -> Dict[str, Any]:
|
|
"""Parse LLM response for analysis."""
|
|
try:
|
|
import json
|
|
# Clean up the response to extract JSON
|
|
response = response.strip()
|
|
if response.startswith("```json"):
|
|
response = response[7:]
|
|
if response.endswith("```"):
|
|
response = response[:-3]
|
|
response = response.strip()
|
|
|
|
return json.loads(response)
|
|
except Exception as e:
|
|
logger.error(f"Error parsing analysis response: {str(e)}")
|
|
return {
|
|
"completeness": 0,
|
|
"coherence": 0,
|
|
"alignment": 0,
|
|
"suggestions": [],
|
|
"missingFields": [],
|
|
"improvements": []
|
|
}
|
|
|
|
def _parse_suggestions_response(self, response: str) -> Dict[str, Any]:
|
|
"""Parse LLM response for suggestions."""
|
|
try:
|
|
import json
|
|
# Clean up the response to extract JSON
|
|
response = response.strip()
|
|
if response.startswith("```json"):
|
|
response = response[7:]
|
|
if response.endswith("```"):
|
|
response = response[:-3]
|
|
response = response.strip()
|
|
|
|
return json.loads(response)
|
|
except Exception as e:
|
|
logger.error(f"Error parsing suggestions response: {str(e)}")
|
|
return {"suggestions": [], "reasoning": "Unable to generate suggestions", "confidence": 0}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 **Implementation Steps**
|
|
|
|
### **Step 1: Install Dependencies**
|
|
```bash
|
|
# Frontend
|
|
npm install @copilotkit/react-core @copilotkit/react-ui
|
|
|
|
# Backend (no CopilotKit dependencies needed)
|
|
# Only need Google GenAI for Gemini
|
|
```
|
|
|
|
### **Step 2: Setup CopilotKit Provider**
|
|
1. Modify `App.tsx` to include CopilotKit provider with public API key
|
|
2. Configure CopilotSidebar with ALwrity branding
|
|
3. Setup observability hooks for analytics
|
|
|
|
### **Step 3: Implement Context Provision**
|
|
1. Add `useCopilotReadable` hooks in ContentStrategyBuilder
|
|
2. Provide form state, field definitions, and onboarding data
|
|
3. Setup dynamic instructions based on current state
|
|
|
|
### **Step 4: Create CopilotKit Actions**
|
|
1. Create `CopilotActions.tsx` component
|
|
2. Implement all 6 core actions
|
|
3. Add error handling and user feedback
|
|
|
|
### **Step 5: Build Backend Services**
|
|
1. Create `strategy_copilot.py` API endpoints
|
|
2. Implement `StrategyCopilotService` with real data integration
|
|
3. Add proper error handling and logging
|
|
|
|
### **Step 6: Integration Testing**
|
|
1. Test all CopilotKit actions
|
|
2. Verify real data integration
|
|
3. Test user experience flows
|
|
|
|
---
|
|
|
|
## 🎯 **Key Features**
|
|
|
|
### **1. Real Data Integration**
|
|
- **Onboarding Data**: Website analysis, research preferences
|
|
- **User History**: Previous strategies and performance
|
|
- **Database Queries**: All data from real database
|
|
- **No Mock Data**: All responses based on actual user data
|
|
|
|
### **2. Contextual Intelligence**
|
|
- **Form State Awareness**: Copilot knows current progress
|
|
- **Field Relationships**: Understands field dependencies
|
|
- **User Preferences**: Uses onboarding data for personalization
|
|
- **Progressive Guidance**: Adapts to user progress
|
|
|
|
### **3. Smart Actions**
|
|
- **Field Population**: Intelligent field filling
|
|
- **Category Population**: Bulk category population
|
|
- **Validation**: Real-time field validation
|
|
- **Strategy Review**: Comprehensive strategy analysis
|
|
- **Suggestions**: Contextual field suggestions
|
|
- **Auto-Population**: Onboarding data integration
|
|
|
|
### **4. User Experience**
|
|
- **Persistent Assistant**: Always available via sidebar
|
|
- **Contextual Greeting**: Adapts based on user progress
|
|
- **Real-time Feedback**: Immediate validation and suggestions
|
|
- **Progress Tracking**: Visual completion indicators
|
|
|
|
---
|
|
|
|
## 🔒 **Security Considerations**
|
|
|
|
### **Data Protection**
|
|
- **User Isolation**: Each user's data is isolated
|
|
- **Authentication**: All actions require user authentication
|
|
- **Input Validation**: Sanitize all user inputs
|
|
- **Error Handling**: Secure error messages
|
|
|
|
### **API Security**
|
|
- **Rate Limiting**: Prevent abuse of AI endpoints
|
|
- **Input Sanitization**: Validate all inputs
|
|
- **Output Validation**: Verify AI responses
|
|
- **Audit Logging**: Track all interactions
|
|
|
|
---
|
|
|
|
## 📊 **Performance Optimization**
|
|
|
|
### **Frontend Optimization**
|
|
- **Selective Re-renders**: Use React.memo for components
|
|
- **Lazy Loading**: Load CopilotKit on demand
|
|
- **Caching**: Cache AI responses where appropriate
|
|
- **Debouncing**: Debounce user inputs
|
|
|
|
### **Backend Optimization**
|
|
- **Response Caching**: Cache common AI responses
|
|
- **Database Optimization**: Optimize database queries
|
|
- **Async Processing**: Use async/await for AI calls
|
|
- **Connection Pooling**: Optimize database connections
|
|
|
|
---
|
|
|
|
## 🧪 **Testing Strategy**
|
|
|
|
### **Unit Tests**
|
|
- **Action Handlers**: Test all CopilotKit actions
|
|
- **Service Methods**: Test backend service methods
|
|
- **Data Parsing**: Test response parsing functions
|
|
- **Error Handling**: Test error scenarios
|
|
|
|
### **Integration Tests**
|
|
- **End-to-End Flows**: Test complete user journeys
|
|
- **API Integration**: Test frontend-backend integration
|
|
- **Data Flow**: Test data flow between components
|
|
- **User Experience**: Test actual user interactions
|
|
|
|
### **Performance Tests**
|
|
- **Response Times**: Test AI response times
|
|
- **Concurrent Users**: Test with multiple users
|
|
- **Memory Usage**: Monitor memory consumption
|
|
- **Database Load**: Test database performance
|
|
|
|
---
|
|
|
|
## 📈 **Monitoring and Analytics**
|
|
|
|
### **User Analytics**
|
|
- **Assistant Usage**: Track CopilotKit interactions
|
|
- **Action Success**: Monitor action success rates
|
|
- **User Satisfaction**: Track user feedback
|
|
- **Completion Rates**: Monitor strategy completion
|
|
|
|
### **Performance Monitoring**
|
|
- **Response Times**: Monitor AI response times
|
|
- **Error Rates**: Track error frequencies
|
|
- **Resource Usage**: Monitor system resources
|
|
- **Database Performance**: Track query performance
|
|
|
|
---
|
|
|
|
## 🚀 **Deployment Checklist**
|
|
|
|
### **Pre-Deployment**
|
|
- [ ] All tests passing
|
|
- [ ] Performance benchmarks met
|
|
- [ ] Security review completed
|
|
- [ ] Documentation updated
|
|
- [ ] User acceptance testing completed
|
|
|
|
### **Deployment**
|
|
- [ ] Environment variables configured
|
|
- [ ] Database migrations applied
|
|
- [ ] API endpoints deployed
|
|
- [ ] Frontend deployed
|
|
- [ ] Monitoring configured
|
|
|
|
### **Post-Deployment**
|
|
- [ ] Health checks passing
|
|
- [ ] User feedback collected
|
|
- [ ] Performance monitored
|
|
- [ ] Issues addressed
|
|
- [ ] Success metrics tracked
|
|
|
|
---
|
|
|
|
## 📝 **Conclusion**
|
|
|
|
This technical specification provides a comprehensive roadmap for integrating CopilotKit into ALwrity's strategy builder. The implementation maintains all existing functionality while adding intelligent AI assistance that significantly improves user experience and data quality.
|
|
|
|
The integration follows best practices for security, performance, and user experience, ensuring a robust and scalable solution that grows with user needs.
|
|
|
|
**Key Success Factors:**
|
|
- Maintain existing functionality
|
|
- Use real data sources
|
|
- Provide intelligent assistance
|
|
- Ensure security and performance
|
|
- Create seamless user experience
|
|
|
|
This implementation positions ALwrity as a leader in AI-powered content strategy creation, providing users with an unmatched experience in building comprehensive, data-driven content strategies.
|