feat: Add AI Assist module - Conversational intelligence with specialized agent switching - Real-time preview for code, design, content, and SEO - Multi-agent routing logic (Content, SEO, SMM, PM, Code, Design) - High-end UI with chat thread and live preview sandbox - Integrated with Ollama, Qwen, and Z.AI services

This commit is contained in:
Gemini AI
2025-12-28 03:35:29 +04:00
Unverified
parent 8f0a65eee1
commit bc627479f1
10 changed files with 681 additions and 118 deletions

View File

@@ -12,6 +12,7 @@ export const translations = {
googleAds: "Google Ads",
uxDesigner: "UX Designer",
marketResearch: "Market Research",
aiAssist: "AI Assist",
settings: "Settings",
history: "History",
},
@@ -148,6 +149,16 @@ export const translations = {
"Synthesizing strategic advantages and identifying gaps...",
"Finalizing comprehensive intelligence report..."
]
},
aiAssist: {
title: "AI Assist",
description: "Conversational intelligence with agent switching",
placeholder: "Discuss any topic, concern or project...",
chatStart: "How can I help you today?",
switchingAgent: "Switching to specialized agent...",
routing: "Routing your request...",
preview: "Real-time Preview",
actions: "Agent Actions"
}
},
ru: {
@@ -161,6 +172,7 @@ export const translations = {
googleAds: "Google Реклама",
uxDesigner: "UX Дизайнер",
marketResearch: "Анализ рынка",
aiAssist: "ИИ Ассистент",
settings: "Настройки",
history: "История",
},
@@ -297,6 +309,16 @@ export const translations = {
"Синтез стратегических преимуществ и выявление пробелов...",
"Финализация подробного отчета о разведке..."
]
},
aiAssist: {
title: "ИИ Ассистент",
description: "Диалоговый интеллект с переключением агентов",
placeholder: "Обсудите любую тему, проблему или проект...",
chatStart: "Чем я могу помочь вам сегодня?",
switchingAgent: "Переключение на специализированного агента...",
routing: "Маршрутизация вашего запроса...",
preview: "Предпросмотр в реальном времени",
actions: "Действия агента"
}
},
he: {
@@ -310,6 +332,7 @@ export const translations = {
googleAds: "Google Ads",
uxDesigner: "מעצב UX",
marketResearch: "מחקר שוק",
aiAssist: "סייען AI",
settings: "הגדרות",
history: "היסטוריה",
},
@@ -446,6 +469,16 @@ export const translations = {
"מסנכרן יתרונות אסטרטגיים ומזהה פערים...",
"מגבש דו\"ח מודיעין מקיף סופי..."
]
},
aiAssist: {
title: "סייען AI",
description: "אינטליגנציה שיחתית עם החלפת סוכנים",
placeholder: "דון בכל נושא, חשש או פרויקט...",
chatStart: "במה אוכל לעזור לך היום?",
switchingAgent: "עובר לסוכן מתמחה...",
routing: "מנתב את הבקשה שלך...",
preview: "תצוגה מקדימה בזמן אמת",
actions: "פעולות סוכן"
}
}
};

View File

@@ -1,4 +1,4 @@
import type { ModelProvider, APIResponse, ChatMessage } from "@/types";
import type { ModelProvider, APIResponse, ChatMessage, AIAssistMessage } from "@/types";
import OllamaCloudService from "./ollama-cloud";
import ZaiPlanService from "./zai-plan";
import qwenOAuthService, { QwenOAuthConfig, QwenOAuthToken } from "./qwen-oauth";
@@ -256,6 +256,19 @@ export class ModelAdapter {
return this.callWithFallback((service) => service.generateMarketResearch(options, model), providers);
}
async generateAIAssist(
options: {
messages: AIAssistMessage[];
currentAgent: string;
},
provider?: ModelProvider,
model?: string
): Promise<APIResponse<string>> {
const fallback = this.buildFallbackProviders(this.preferredProvider, "qwen", "ollama", "zai");
const providers: ModelProvider[] = provider ? [provider] : fallback;
return this.callWithFallback((service) => service.generateAIAssist(options, model), providers);
}
async chatCompletion(
messages: ChatMessage[],

View File

@@ -1,4 +1,4 @@
import type { ChatMessage, APIResponse } from "@/types";
import type { ChatMessage, APIResponse, AIAssistMessage } from "@/types";
export interface OllamaCloudConfig {
apiKey?: string;
@@ -617,71 +617,119 @@ Perform a DEEP 360° competitive intelligence analysis and generate 5-7 strategi
},
model?: string
): Promise<APIResponse<string>> {
const { websiteUrl, additionalUrls = [], competitors = [], productMapping, specialInstructions = "" } = options;
const systemMessage: ChatMessage = {
role: "system",
content: `You are a WORLD-CLASS Market Research Analyst and Competitive Intelligence Expert. Your task is to perform a deep-dive automated market analysis and competitive intelligence gathering.
OUTPUT FORMAT - Return ONLY valid JSON with this structure:
\`\`\`json
{
"executiveSummary": "High-level overview of findings",
"priceComparisonMatrix": [
const systemPrompt = `You are a WORLD-CLASS Market Research Analyst and Competitive Intelligence Expert.
Your objective is to perform a deep-dive analysis of a business and its competitors based on provided URLs and product mappings.
You MUST return your analysis in the following STRICT JSON format:
{
"product": "Product Name",
"userPrice": "$XX.XX",
"competitorPrices": [
{ "competitor": "Competitor Name", "price": "$XX.XX", "url": "https://competitor.com/product-page" }
]
"executiveSummary": "A concise overview of the market landscape and key findings.",
"priceComparisonMatrix": [
{
"product": "Product Name",
"userPrice": "$XX.XX",
"competitorPrices": [
{ "competitor": "Competitor Name", "price": "$XX.XX", "url": "https://competitor.com/product-page" }
]
}
],
"featureComparisonTable": [
{
"feature": "Feature Name",
"userStatus": true/false/text,
"competitorStatus": [
{ "competitor": "Competitor Name", "status": true/false/text }
]
}
],
"marketPositioning": {
"landscape": "Description of the current market state.",
"segmentation": "Analysis of target customer segments."
},
"competitiveAnalysis": {
"advantages": ["Point 1", "Point 2"],
"disadvantages": ["Point 1", "Point 2"]
},
"recommendations": ["Actionable step 1", "Actionable step 2"],
"methodology": "Brief description of the research process."
}
],
"featureComparisonTable": [
Requirements:
1. Base your analysis on realistic price and feature estimates if exact data isn't visible.
2. Focus on core technical/business value rather than marketing fluff.
3. Ensure JSON is valid and properly escaped.`;
const userMsg = `WEBSITE TO ANALYZE: ${options.websiteUrl}
ADDITIONAL COMPANY URLS: ${options.additionalUrls?.join(', ') || 'None'}
COMPETITOR URLS: ${options.competitors.join(', ')}
PRODUCT/FEATURE MAPPING: ${options.productMapping}
SPECIAL REQUESTS: ${options.specialInstructions || 'Perform comprehensive analysis'}
Provide a COMPREHENSIVE competitive intelligence report.`;
const messages: ChatMessage[] = [
{ role: "system", content: systemPrompt },
{ role: "user", content: userMsg }
];
return await this.chatCompletion(messages, model || this.getAvailableModels()[0]);
}
async generateAIAssist(
options: {
messages: AIAssistMessage[];
currentAgent: string;
},
model?: string
): Promise<APIResponse<string>> {
const systemPrompt = `You are "AI Assist", the master orchestrator of PromptArch.
Your goal is to provide intelligent conversational support and switch to specialized agents when necessary.
CURRENT SPECIALIZED AGENTS:
- content: Content creation and optimization expert.
- seo: SEO analyst and recommendations specialist.
- smm: SMM strategy and social content planner.
- pm: Project planning and management lead.
- code: Code architect (JavaScript/TypeScript/React focus).
- design: UI/UX designer.
- web: HTML/CSS/JS web development specialist with real-time preview.
- app: Mobile-first app development specialist with real-time preview.
STRICT OUTPUT FORMAT:
You MUST respond in JSON format if you want to activate a preview or switch agents.
{
"feature": "Feature Name",
"userStatus": "Yes/No or description",
"competitorStatus": [
{ "competitor": "Competitor Name", "status": "Yes/No or description" }
]
"content": "Your natural language response here...",
"agent": "agent_id_to_switch_to (optional)",
"preview": { // (optional)
"type": "code" | "design" | "content" | "seo",
"data": "The actual code, layout, or content to preview",
"language": "javascript/html/css/markdown (optional)"
}
}
],
"marketPositioning": {
"landscape": "Current market landscape description",
"segmentation": "Target market segments"
},
"competitiveAnalysis": {
"advantages": ["Point 1", "Point 2"],
"disadvantages": ["Point 1", "Point 2"]
},
"recommendations": ["Rec 1", "Rec 2"],
"methodology": "How the research was conducted"
}
\`\`\`
REQUIREMENTS:
- Analysis must be based on the provided website and competitor URLs.
- Price comparison should be as realistic as possible based on industry knowledge.
- Feature table should focus on core technical and business value.
- Competitive analysis must highlight USP (Unique Selling Proposition).`,
};
ROUTING LOGIC:
- If user asks for code, switch to 'code' or 'web'.
- If user asks for design/mockups, switch to 'design'.
- If user asks for market/SEO, switch to 'seo'.
- If user asks for marketing/social, switch to 'smm'.
- Maintain the 'content' of the conversation regardless of the agent switch.
const userMessage: ChatMessage = {
role: "user",
content: `🔬 MARKET RESEARCH REQUEST 🔬
PREVIEW GUIDELINES:
- For 'web'/'app', provide full runnable HTML/CSS/JS.
- For 'code', provide clean, commented snippets.
- For 'design', provide text-based UI components or layout structures.
RESPONSE TIME REQUIREMENT: Be concise and accurate.`;
PRIMARY WEBSITE: ${websiteUrl}
ADDITIONAL PAGES: ${additionalUrls.join(", ")}
COMPETITORS: ${competitors.join(", ")}
PRODUCT COMPARISON MAPPING: ${productMapping}
${specialInstructions ? `CUSTOM PARAMETERS: ${specialInstructions}` : ""}
const chatMessages: ChatMessage[] = [
{ role: "system", content: systemPrompt },
...options.messages.map(m => ({
role: m.role as "user" | "assistant" | "system",
content: m.content
}))
];
Please conduct a comprehensive competitive analysis and market research report.`,
};
return this.chatCompletion([systemMessage, userMessage], model || "gpt-oss:120b");
return await this.chatCompletion(chatMessages, model || this.getAvailableModels()[0]);
}
}
export default OllamaCloudService;

View File

@@ -1,4 +1,4 @@
import type { ChatMessage, APIResponse } from "@/types";
import type { ChatMessage, APIResponse, AIAssistMessage } from "@/types";
const DEFAULT_QWEN_ENDPOINT = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
const TOKEN_STORAGE_KEY = "promptarch-qwen-tokens";
@@ -983,6 +983,29 @@ Perform analysis based on provided instructions.`,
return this.chatCompletion([systemMessage, userMessage], model || "coder-model");
}
async generateAIAssist(
options: {
messages: AIAssistMessage[];
currentAgent: string;
},
model?: string
): Promise<APIResponse<string>> {
const systemPrompt = `You are "AI Assist". Help conversationally.
Switch agents if needed (content, seo, smm, pm, code, design, web, app).
Output JSON for previews or agent switches:
{ "content": "text", "agent": "id", "preview": { "type": "code|design|content|seo", "data": "...", "language": "..." } }`;
const chatMessages: ChatMessage[] = [
{ role: "system", content: systemPrompt },
...options.messages.map(m => ({
role: m.role as "user" | "assistant" | "system",
content: m.content
}))
];
return await this.chatCompletion(chatMessages, model || this.getAvailableModels()[0]);
}
async listModels(): Promise<APIResponse<string[]>> {
const models = [
"coder-model",
@@ -999,6 +1022,5 @@ Perform analysis based on provided instructions.`,
const qwenOAuthService = new QwenOAuthService();
export default qwenOAuthService;
export { qwenOAuthService };

View File

@@ -1,4 +1,4 @@
import type { ChatMessage, APIResponse } from "@/types";
import type { ChatMessage, APIResponse, AIAssistMessage } from "@/types";
export interface ZaiPlanConfig {
apiKey?: string;
@@ -700,67 +700,105 @@ MISSION: Perform a DEEP 360° competitive intelligence analysis and generate 5-7
): Promise<APIResponse<string>> {
const { websiteUrl, additionalUrls = [], competitors = [], productMapping, specialInstructions = "" } = options;
const systemMessage: ChatMessage = {
role: "system",
content: `You are a WORLD-CLASS Market Research Analyst and Competitive Intelligence Expert. Perform a deep-dive automated market analysis.
OUTPUT FORMAT - Return ONLY valid JSON with this structure:
\`\`\`json
{
"executiveSummary": "High-level overview of findings",
"priceComparisonMatrix": [
const systemPrompt = `You are a WORLD-CLASS Market Research Analyst and Competitive Intelligence Expert.
Focus on accuracy and actionable intelligence.
You MUST return your analysis in the following STRICT JSON format:
{
"product": "Product Name",
"userPrice": "$XX.XX",
"competitorPrices": [
{ "competitor": "Competitor Name", "price": "$XX.XX", "url": "https://competitor.com/product-page" }
]
"executiveSummary": "A concise overview of the market landscape and key findings.",
"priceComparisonMatrix": [
{
"product": "Product Name",
"userPrice": "$XX.XX",
"competitorPrices": [
{ "competitor": "Competitor Name", "price": "$XX.XX", "url": "https://competitor.com/product-page" }
]
}
],
"featureComparisonTable": [
{
"feature": "Feature Name",
"userStatus": true/false/text,
"competitorStatus": [
{ "competitor": "Competitor Name", "status": true/false/text }
]
}
],
"marketPositioning": {
"landscape": "Description of the current market state.",
"segmentation": "Analysis of target customer segments."
},
"competitiveAnalysis": {
"advantages": ["Point 1", "Point 2"],
"disadvantages": ["Point 1", "Point 2"]
},
"recommendations": ["Actionable step 1", "Actionable step 2"],
"methodology": "Brief description of the research process."
}
],
"featureComparisonTable": [
Requirements:
1. Base your analysis on realistic price and feature estimates.
2. Focus on core technical/business value.
3. Ensure JSON is valid.`;
const userMsg = `WEBSITE TO ANALYZE: ${options.websiteUrl}
COMPETITOR URLS: ${options.competitors.join(', ')}
PRODUCT/FEATURE MAPPING: ${options.productMapping}
SPECIAL REQUESTS: ${options.specialInstructions || 'Perform comprehensive analysis'}
Provide a COMPREHENSIVE competitive intelligence analysis.`;
const messages: ChatMessage[] = [
{ role: "system", content: systemPrompt },
{ role: "user", content: userMsg }
];
return await this.chatCompletion(messages, model || this.getAvailableModels()[0]);
}
async generateAIAssist(
options: {
messages: AIAssistMessage[];
currentAgent: string;
},
model?: string
): Promise<APIResponse<string>> {
const systemPrompt = `You are "AI Assist", the master orchestrator of PromptArch.
Your goal is to provide intelligent conversational support and switch to specialized agents when necessary.
CURRENT SPECIALIZED AGENTS:
- content, seo, smm, pm, code, design, web, app
STRICT OUTPUT FORMAT:
You MUST respond in JSON format if you want to activate a preview or switch agents.
{
"feature": "Feature Name",
"userStatus": "Yes/No or description",
"competitorStatus": [
{ "competitor": "Competitor Name", "status": "Yes/No or description" }
]
"content": "Your natural language response here...",
"agent": "agent_id_to_switch_to (optional)",
"preview": { // (optional)
"type": "code" | "design" | "content" | "seo",
"data": "The actual code, layout, or content to preview",
"language": "javascript/html/css/markdown (optional)"
}
}
],
"marketPositioning": {
"landscape": "Current market landscape description",
"segmentation": "Target market segments"
},
"competitiveAnalysis": {
"advantages": ["Point 1", "Point 2"],
"disadvantages": ["Point 1", "Point 2"]
},
"recommendations": ["Rec 1", "Rec 2"],
"methodology": "How the research was conducted"
}
\`\`\`
REQUIREMENTS:
- Focus on accuracy and actionable intelligence.
- Be realistic with price and feature estimates based on the provided URLs.`,
};
ROUTING LOGIC:
- Automatically detect user intent and switch agents if appropriate.
- Provide deep technical or creative output based on the active agent.
PREVIEW GUIDELINES:
- Provide full code for 'web'/'app'/'code'.
- Provide structured analysis for 'seo'/'content'.`;
const userMessage: ChatMessage = {
role: "user",
content: `🔬 MARKET RESEARCH REQUEST 🔬
const chatMessages: ChatMessage[] = [
{ role: "system", content: systemPrompt },
...options.messages.map(m => ({
role: m.role as "user" | "assistant" | "system",
content: m.content
}))
];
PRIMARY WEBSITE: ${websiteUrl}
ADDITIONAL PAGES: ${additionalUrls.join(", ")}
COMPETITORS: ${competitors.join(", ")}
PRODUCT COMPARISON MAPPING: ${productMapping}
${specialInstructions ? `CUSTOM PARAMETERS: ${specialInstructions}` : ""}
Perform a COMPREHENSIVE competitive intelligence analysis.`,
};
return this.chatCompletion([systemMessage, userMessage], model || "glm-4.7", true);
return await this.chatCompletion(chatMessages, model || this.getAvailableModels()[0]);
}
}
export default ZaiPlanService;

View File

@@ -1,5 +1,5 @@
import { create } from "zustand";
import type { ModelProvider, PromptEnhancement, PRD, ActionPlan, SlidesPresentation, GoogleAdsResult, MagicWandResult, MarketResearchResult, AppView } from "@/types";
import type { ModelProvider, PromptEnhancement, PRD, ActionPlan, SlidesPresentation, GoogleAdsResult, MagicWandResult, MarketResearchResult, AppView, AIAssistMessage } from "@/types";
interface AppState {
currentPrompt: string;
@@ -10,6 +10,7 @@ interface AppState {
googleAdsResult: GoogleAdsResult | null;
magicWandResult: MagicWandResult | null;
marketResearchResult: MarketResearchResult | null;
aiAssistHistory: AIAssistMessage[];
language: "en" | "ru" | "he";
selectedProvider: ModelProvider;
selectedModels: Record<ModelProvider, string>;
@@ -36,6 +37,7 @@ interface AppState {
setGoogleAdsResult: (result: GoogleAdsResult | null) => void;
setMagicWandResult: (result: MagicWandResult | null) => void;
setMarketResearchResult: (result: MarketResearchResult | null) => void;
setAIAssistHistory: (history: AIAssistMessage[] | ((prev: AIAssistMessage[]) => AIAssistMessage[])) => void;
setLanguage: (lang: "en" | "ru" | "he") => void;
setSelectedProvider: (provider: ModelProvider) => void;
setSelectedModel: (provider: ModelProvider, model: string) => void;
@@ -58,6 +60,7 @@ const useStore = create<AppState>((set) => ({
googleAdsResult: null,
magicWandResult: null,
marketResearchResult: null,
aiAssistHistory: [],
language: "en",
selectedProvider: "qwen",
selectedModels: {
@@ -87,6 +90,9 @@ const useStore = create<AppState>((set) => ({
setGoogleAdsResult: (result) => set({ googleAdsResult: result }),
setMagicWandResult: (result) => set({ magicWandResult: result }),
setMarketResearchResult: (result) => set({ marketResearchResult: result }),
setAIAssistHistory: (update) => set((state) => ({
aiAssistHistory: typeof update === 'function' ? update(state.aiAssistHistory) : update
})),
setLanguage: (lang) => set({ language: lang }),
setSelectedProvider: (provider) => set({ selectedProvider: provider }),
setSelectedModel: (provider, model) =>
@@ -126,6 +132,7 @@ const useStore = create<AppState>((set) => ({
googleAdsResult: null,
magicWandResult: null,
marketResearchResult: null,
aiAssistHistory: [],
error: null,
}),
}));