- Added GoogleAdsGenerator component with comprehensive keyword research and ad copy generation. - Updated Sidebar and Home page for navigation. - Added necessary UI components (Badge, Tabs) and dependencies. - Added custom animations for progress indicators.
534 lines
17 KiB
TypeScript
534 lines
17 KiB
TypeScript
import type { ChatMessage, APIResponse } from "@/types";
|
|
|
|
export interface OllamaCloudConfig {
|
|
apiKey?: string;
|
|
endpoint?: string;
|
|
}
|
|
|
|
const BASE_PATH = "/tools/promptarch";
|
|
const LOCAL_MODELS_URL = `${BASE_PATH}/api/ollama/models`;
|
|
const LOCAL_CHAT_URL = `${BASE_PATH}/api/ollama/chat`;
|
|
const DEFAULT_MODELS = [
|
|
"gpt-oss:120b",
|
|
"llama3.1:latest",
|
|
"llama3.1:70b",
|
|
"llama3.1:8b",
|
|
"llama3.1:instruct",
|
|
"gemma3:12b",
|
|
"gemma3:27b",
|
|
"gemma3:4b",
|
|
"gemma3:7b",
|
|
"deepseek-r1:70b",
|
|
"deepseek-r1:32b",
|
|
"deepseek-r1:14b",
|
|
"deepseek-r1:8b",
|
|
"deepseek-r1:1.5b",
|
|
"qwen3:72b",
|
|
"qwen3:32b",
|
|
"qwen3:14b",
|
|
"qwen3:7b",
|
|
"qwen3:4b",
|
|
"mistral:7b",
|
|
"mistral:instruct",
|
|
"codellama:34b",
|
|
"codellama:13b",
|
|
"codellama:7b",
|
|
"codellama:instruct",
|
|
"phi3:14b",
|
|
"phi3:3.8b",
|
|
"phi3:mini",
|
|
"gemma2:27b",
|
|
"gemma2:9b",
|
|
"yi:34b",
|
|
"yi:9b",
|
|
];
|
|
|
|
export class OllamaCloudService {
|
|
private config: OllamaCloudConfig;
|
|
private availableModels: string[] = [];
|
|
|
|
constructor(config: OllamaCloudConfig = {}) {
|
|
this.config = {
|
|
apiKey: config.apiKey || process.env.OLLAMA_API_KEY,
|
|
endpoint: config.endpoint,
|
|
};
|
|
}
|
|
|
|
hasAuth(): boolean {
|
|
return !!this.config.apiKey;
|
|
}
|
|
|
|
private ensureApiKey(): string {
|
|
if (this.config.apiKey) {
|
|
return this.config.apiKey;
|
|
}
|
|
throw new Error("API key is required. Please configure your Ollama API key in settings.");
|
|
}
|
|
|
|
private getHeaders(additional: Record<string, string> = {}) {
|
|
const headers: Record<string, string> = {
|
|
...additional,
|
|
"x-ollama-api-key": this.ensureApiKey(),
|
|
};
|
|
|
|
if (this.config.endpoint) {
|
|
headers["x-ollama-endpoint"] = this.config.endpoint;
|
|
}
|
|
|
|
return headers;
|
|
}
|
|
|
|
private async parseJsonResponse(response: Response): Promise<any> {
|
|
const text = await response.text();
|
|
if (!text) return null;
|
|
return JSON.parse(text);
|
|
}
|
|
|
|
async chatCompletion(
|
|
messages: ChatMessage[],
|
|
model: string = "gpt-oss:120b",
|
|
stream: boolean = false
|
|
): Promise<APIResponse<string>> {
|
|
try {
|
|
const response = await fetch(LOCAL_CHAT_URL, {
|
|
method: "POST",
|
|
headers: this.getHeaders({ "Content-Type": "application/json" }),
|
|
body: JSON.stringify({
|
|
model,
|
|
messages,
|
|
stream,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorBody = await response.text();
|
|
throw new Error(
|
|
`Chat completion failed (${response.status}): ${response.statusText} - ${errorBody}`
|
|
);
|
|
}
|
|
|
|
const data = await this.parseJsonResponse(response);
|
|
if (data?.message?.content) {
|
|
return { success: true, data: data.message.content };
|
|
}
|
|
|
|
if (data?.choices?.[0]?.message?.content) {
|
|
return { success: true, data: data.choices[0].message.content };
|
|
}
|
|
|
|
return { success: false, error: "Unexpected response format" };
|
|
} catch (error) {
|
|
console.error("[Ollama] Chat completion error:", error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Chat completion failed",
|
|
};
|
|
}
|
|
}
|
|
|
|
async listModels(): Promise<APIResponse<string[]>> {
|
|
try {
|
|
const response = await fetch(LOCAL_MODELS_URL, {
|
|
headers: this.getHeaders(),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorBody = await response.text();
|
|
throw new Error(`List models failed: ${response.statusText} - ${errorBody}`);
|
|
}
|
|
|
|
const data = await this.parseJsonResponse(response);
|
|
const models: string[] = Array.isArray(data?.models) ? data.models : [];
|
|
|
|
if (models.length === 0) {
|
|
this.availableModels = DEFAULT_MODELS;
|
|
return { success: true, data: DEFAULT_MODELS };
|
|
}
|
|
|
|
this.availableModels = models;
|
|
return { success: true, data: models };
|
|
} catch (error) {
|
|
console.error("[Ollama] listModels error:", error);
|
|
if (DEFAULT_MODELS.length > 0) {
|
|
this.availableModels = DEFAULT_MODELS;
|
|
return { success: true, data: DEFAULT_MODELS };
|
|
}
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : "Failed to list models",
|
|
};
|
|
}
|
|
}
|
|
|
|
getAvailableModels(): string[] {
|
|
return this.availableModels.length > 0 ? this.availableModels : DEFAULT_MODELS;
|
|
}
|
|
|
|
async enhancePrompt(prompt: string, model?: string): Promise<APIResponse<string>> {
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are an expert prompt engineer. Your task is to enhance user prompts to make them more precise, actionable, and effective for AI coding agents.
|
|
|
|
Apply these principles:
|
|
1. Add specific context about project and requirements
|
|
2. Clarify constraints and preferences
|
|
3. Define expected output format clearly
|
|
4. Include edge cases and error handling requirements
|
|
5. Specify testing and validation criteria
|
|
|
|
Return ONLY the enhanced prompt, no explanations or extra text.`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Enhance this prompt for an AI coding agent:\n\n${prompt}`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
|
|
async generatePRD(idea: string, model?: string): Promise<APIResponse<string>> {
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are an expert product manager and technical architect. Generate a comprehensive Product Requirements Document (PRD) based on user's idea.
|
|
|
|
Structure your PRD with these sections:
|
|
1. Overview & Objectives
|
|
2. User Personas & Use Cases
|
|
3. Functional Requirements (prioritized)
|
|
4. Non-functional Requirements
|
|
5. Technical Architecture Recommendations
|
|
6. Success Metrics & KPIs
|
|
|
|
Use clear, specific language suitable for development teams.`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Generate a PRD for this idea:\n\n${idea}`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
|
|
async generateActionPlan(prd: string, model?: string): Promise<APIResponse<string>> {
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are an expert technical lead and project manager. Generate a detailed action plan based on PRD.
|
|
|
|
Structure of action plan with:
|
|
1. Task breakdown with priorities (High/Medium/Low)
|
|
2. Dependencies between tasks
|
|
3. Estimated effort for each task
|
|
4. Recommended frameworks and technologies
|
|
5. Architecture guidelines and best practices
|
|
|
|
Include specific recommendations for:
|
|
- Frontend frameworks
|
|
- Backend architecture
|
|
- Database choices
|
|
- Authentication/authorization
|
|
- Deployment strategy`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Generate an action plan based on this PRD:\n\n${prd}`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
|
|
async generateUXDesignerPrompt(appDescription: string, model?: string): Promise<APIResponse<string>> {
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are a world-class UX/UI designer with deep expertise in human-centered design principles, user research, interaction design, visual design systems, and modern design tools (Figma, Sketch, Adobe XD).
|
|
|
|
Your task is to create an exceptional, detailed prompt for generating best possible UX design for a given app description.
|
|
|
|
Generate a comprehensive UX design prompt that includes:
|
|
|
|
1. USER RESEARCH & PERSONAS
|
|
- Primary target users and their motivations
|
|
- User pain points and needs
|
|
- User journey maps
|
|
- Persona archetypes with demographics and goals
|
|
|
|
2. INFORMATION ARCHITECTURE
|
|
- Content hierarchy and organization
|
|
- Navigation structure and patterns
|
|
- User flows and key pathways
|
|
- Site map or app structure
|
|
|
|
3. VISUAL DESIGN SYSTEM
|
|
- Color palette recommendations (primary, secondary, accent, neutral)
|
|
- Typography hierarchy and font pairings
|
|
- Component library approach
|
|
- Spacing, sizing, and layout grids
|
|
- Iconography style and set
|
|
|
|
4. INTERACTION DESIGN
|
|
- Micro-interactions and animations
|
|
- Gesture patterns for touch interfaces
|
|
- Loading states and empty states
|
|
- Error handling and feedback mechanisms
|
|
- Accessibility considerations (WCAG compliance)
|
|
|
|
5. KEY SCREENS & COMPONENTS
|
|
- Core screens that need detailed design
|
|
- Critical components (buttons, forms, cards, navigation)
|
|
- Data visualization needs
|
|
- Responsive design requirements (mobile, tablet, desktop)
|
|
|
|
6. DESIGN DELIVERABLES
|
|
- Wireframes vs. high-fidelity mockups
|
|
- Design system documentation needs
|
|
- Prototyping requirements
|
|
- Handoff specifications for developers
|
|
|
|
7. COMPETITIVE INSIGHTS
|
|
- Design patterns from successful apps in this category
|
|
- Opportunities to differentiate
|
|
- Modern design trends to consider
|
|
|
|
The output should be a detailed, actionable prompt that a designer or AI image generator can use to create world-class UX designs.
|
|
|
|
Make's prompt specific, inspiring, and comprehensive. Use professional UX terminology.`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Create a BEST EVER UX design prompt for this app:\n\n${appDescription}`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
|
|
async generateSlides(
|
|
topic: string,
|
|
options: {
|
|
language?: string;
|
|
theme?: string;
|
|
slideCount?: number;
|
|
audience?: string;
|
|
organization?: string;
|
|
animationStyle?: string;
|
|
audienceStyle?: string;
|
|
themeColors?: string[];
|
|
brandColors?: string[];
|
|
} = {},
|
|
model?: string
|
|
): Promise<APIResponse<string>> {
|
|
const {
|
|
language = "English",
|
|
theme = "executive-dark",
|
|
slideCount = 10,
|
|
audience = "Executives & C-Suite",
|
|
organization = "",
|
|
animationStyle = "Professional",
|
|
audienceStyle = "Sophisticated, data-driven, strategic focus",
|
|
themeColors = ["#09090b", "#6366f1", "#a855f7", "#fafafa"],
|
|
brandColors = []
|
|
} = options;
|
|
|
|
const [bgColor, primaryColor, secondaryColor, textColor] = themeColors;
|
|
const brandColorStr = brandColors.length > 0
|
|
? `\nBRAND COLORS TO USE: ${brandColors.join(", ")}`
|
|
: "";
|
|
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are a WORLD-CLASS presentation designer who creates STUNNING, AWARD-WINNING slide decks that rival McKinsey, Apple, and TED presentations.
|
|
|
|
Your slides must be VISUALLY SPECTACULAR with:
|
|
- Modern CSS3 animations (fade-in, slide-in, scale, parallax effects)
|
|
- Sophisticated gradient backgrounds with depth
|
|
- SVG charts and data visualizations inline
|
|
- Glassmorphism and neumorphism effects
|
|
- Professional typography with Inter/SF Pro fonts
|
|
- Strategic use of whitespace
|
|
- Micro-animations on hover/focus states
|
|
- Progress indicators and visual hierarchy
|
|
|
|
OUTPUT FORMAT - Return ONLY valid JSON:
|
|
\`\`\`json
|
|
{
|
|
"title": "Presentation Title",
|
|
"subtitle": "Compelling Subtitle",
|
|
"theme": "${theme}",
|
|
"language": "${language}",
|
|
"slides": [
|
|
{
|
|
"id": "slide-1",
|
|
"title": "Slide Title",
|
|
"content": "Plain text content summary",
|
|
"htmlContent": "<div>FULL HTML with inline CSS and animations</div>",
|
|
"notes": "Speaker notes",
|
|
"layout": "title|content|two-column|chart|statistics|timeline|quote|comparison",
|
|
"order": 1
|
|
}
|
|
]
|
|
}
|
|
\`\`\`
|
|
|
|
DESIGN SYSTEM:
|
|
- Primary: ${brandColors[0] || primaryColor}
|
|
- Secondary: ${brandColors[1] || secondaryColor}
|
|
- Background: ${bgColor}
|
|
- Text: ${textColor}${brandColorStr}
|
|
|
|
ANIMATION STYLE: ${animationStyle}
|
|
- Professional: Subtle 0.3-0.5s ease transitions, fade and slide
|
|
- Dynamic: 0.5-0.8s spring animations, emphasis effects, stagger delays
|
|
- Impressive: Bold 0.8-1.2s animations, parallax, morphing, particle effects
|
|
|
|
CSS ANIMATIONS TO INCLUDE:
|
|
\`\`\`css
|
|
@keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
|
|
@keyframes slideInLeft { from { opacity: 0; transform: translateX(-50px); } to { opacity: 1; transform: translateX(0); } }
|
|
@keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
|
|
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } }
|
|
\`\`\`
|
|
|
|
SLIDE TYPES TO CREATE:
|
|
1. TITLE SLIDE: Hero-style with animated gradient background, large typography
|
|
2. AGENDA/OVERVIEW: Icon grid with staggered fade-in animations
|
|
3. DATA/CHARTS: Inline SVG bar/line/pie charts with animated drawing effects
|
|
4. KEY METRICS: Large animated numbers with KPI cards
|
|
5. TIMELINE: Horizontal/vertical timeline with sequential reveal animations
|
|
6. COMPARISON: Side-by-side cards with hover lift effects
|
|
7. QUOTE: Large typography with decorative quote marks
|
|
8. CALL-TO-ACTION: Bold CTA with pulsing button effect
|
|
|
|
TARGET AUDIENCE: ${audience}
|
|
AUDIENCE STYLE: ${audienceStyle}
|
|
${organization ? `ORGANIZATION BRANDING: ${organization}` : ""}
|
|
|
|
REQUIREMENTS:
|
|
- Create EXACTLY ${slideCount} slides
|
|
- ALL content in ${language}
|
|
- Each slide MUST have complete htmlContent with inline <style> tags
|
|
- Use animation-delay for staggered reveal effects
|
|
- Include decorative background elements (gradients, shapes)
|
|
- Ensure text contrast meets WCAG AA standards
|
|
- Add subtle shadow/glow effects for depth`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Create a STUNNING, ANIMATED presentation about:
|
|
|
|
${topic}
|
|
|
|
SPECIFICATIONS:
|
|
- Language: ${language}
|
|
- Theme: ${theme}
|
|
- Slides: ${slideCount}
|
|
- Audience: ${audience} (${audienceStyle})
|
|
- Animation Style: ${animationStyle}
|
|
${organization ? `- Organization: ${organization}` : ""}
|
|
${brandColors.length > 0 ? `- Brand Colors: ${brandColors.join(", ")}` : ""}
|
|
|
|
Generate SPECTACULAR slides with CSS3 animations, SVG charts, modern gradients, and corporate-ready design!`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
|
|
async generateGoogleAds(
|
|
websiteUrl: string,
|
|
options: {
|
|
productsServices: string[];
|
|
targetAudience?: string;
|
|
budgetRange?: { min: number; max: number; currency: string };
|
|
campaignDuration?: string;
|
|
industry?: string;
|
|
competitors?: string[];
|
|
language?: string;
|
|
} = { productsServices: [] },
|
|
model?: string
|
|
): Promise<APIResponse<string>> {
|
|
const {
|
|
productsServices = [],
|
|
targetAudience = "General consumers",
|
|
budgetRange,
|
|
campaignDuration,
|
|
industry = "General",
|
|
competitors = [],
|
|
language = "English"
|
|
} = options;
|
|
|
|
const systemMessage: ChatMessage = {
|
|
role: "system",
|
|
content: `You are an EXPERT Google Ads strategist. Create HIGH-CONVERTING campaigns with comprehensive keyword research, compelling ad copy, and optimized campaign structures.
|
|
|
|
OUTPUT FORMAT - Return ONLY valid JSON with this structure:
|
|
\`\`\`json
|
|
{
|
|
"keywords": {
|
|
"primary": [{"keyword": "term", "type": "primary", "searchVolume": 12000, "competition": "medium", "cpc": "$2.50"}],
|
|
"longTail": [{"keyword": "specific term", "type": "long-tail", "searchVolume": 1200, "competition": "low", "cpc": "$1.25"}],
|
|
"negative": [{"keyword": "exclude term", "type": "negative", "competition": "low"}]
|
|
},
|
|
"adCopies": [{
|
|
"id": "ad-1",
|
|
"campaignType": "search",
|
|
"headlines": ["Headline 1 (30 chars)", "Headline 2", "Headline 3"],
|
|
"descriptions": ["Description 1 (90 chars)", "Description 2"],
|
|
"callToAction": "Get Started",
|
|
"mobileOptimized": true
|
|
}],
|
|
"campaigns": [{
|
|
"id": "campaign-1",
|
|
"name": "Campaign Name",
|
|
"type": "search",
|
|
"budget": {"daily": 50, "monthly": 1500, "currency": "USD"},
|
|
"targeting": {"locations": [], "demographics": [], "devices": []},
|
|
"adGroups": [{"id": "adgroup-1", "name": "Group", "theme": "Theme", "keywords": [], "biddingStrategy": "Maximize conversions"}]
|
|
}],
|
|
"implementation": {
|
|
"setupSteps": [],
|
|
"qualityScoreTips": [],
|
|
"trackingSetup": [],
|
|
"optimizationTips": []
|
|
},
|
|
"predictions": {
|
|
"estimatedClicks": "500-800/month",
|
|
"estimatedImpressions": "15,000-25,000/month",
|
|
"estimatedCtr": "3.2%-4.5%",
|
|
"estimatedConversions": "25-50/month"
|
|
}
|
|
}
|
|
\`\`\`
|
|
|
|
Requirements:
|
|
- 10-15 primary keywords, 15-20 long-tail, 5-10 negative
|
|
- Headlines max 30 chars, descriptions max 90 chars
|
|
- 3-5 ad variations per campaign
|
|
- Include budget and targeting recommendations`,
|
|
};
|
|
|
|
const userMessage: ChatMessage = {
|
|
role: "user",
|
|
content: `Create a Google Ads campaign for:
|
|
|
|
WEBSITE: ${websiteUrl}
|
|
PRODUCTS/SERVICES: ${productsServices.join(", ")}
|
|
TARGET AUDIENCE: ${targetAudience}
|
|
INDUSTRY: ${industry}
|
|
LANGUAGE: ${language}
|
|
${budgetRange ? `BUDGET: ${budgetRange.min}-${budgetRange.max} ${budgetRange.currency}/month` : ""}
|
|
${campaignDuration ? `DURATION: ${campaignDuration}` : ""}
|
|
${competitors.length > 0 ? `COMPETITORS: ${competitors.join(", ")}` : ""}
|
|
|
|
Generate complete Google Ads package with keywords, ad copy, campaigns, and implementation guidance.`,
|
|
};
|
|
|
|
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
|
|
}
|
|
}
|
|
|
|
export default OllamaCloudService;
|
|
|
|
|