package agent import ( "strings" ) type FocusMode string const ( FocusModeAll FocusMode = "all" FocusModeAcademic FocusMode = "academic" FocusModeWriting FocusMode = "writing" FocusModeYouTube FocusMode = "youtube" FocusModeReddit FocusMode = "reddit" FocusModeCode FocusMode = "code" FocusModeNews FocusMode = "news" FocusModeImages FocusMode = "images" FocusModeMath FocusMode = "math" FocusModeFinance FocusMode = "finance" FocusModeTravel FocusMode = "travel" ) type FocusModeConfig struct { Mode FocusMode Engines []string Categories []string SystemPrompt string SearchQueryPrefix string MaxSources int RequiresCitation bool AllowScraping bool } var FocusModeConfigs = map[FocusMode]FocusModeConfig{ FocusModeAll: { Mode: FocusModeAll, Engines: []string{"google", "bing", "duckduckgo"}, Categories: []string{"general"}, MaxSources: 15, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are a helpful AI assistant that provides comprehensive answers based on web search results. Always cite your sources using [1], [2], etc. format. Provide balanced, accurate information from multiple perspectives.`, }, FocusModeAcademic: { Mode: FocusModeAcademic, Engines: []string{"google scholar", "arxiv", "pubmed", "semantic scholar"}, Categories: []string{"science"}, SearchQueryPrefix: "research paper", MaxSources: 20, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are an academic research assistant specializing in scholarly sources. Focus on peer-reviewed papers, academic journals, and reputable research institutions. Always cite sources in academic format with [1], [2], etc. Distinguish between primary research, meta-analyses, and review articles. Mention publication dates, authors, and journals when available. Be precise about confidence levels and note when findings are preliminary or contested.`, }, FocusModeWriting: { Mode: FocusModeWriting, Engines: []string{"google"}, Categories: []string{"general"}, MaxSources: 5, RequiresCitation: false, AllowScraping: false, SystemPrompt: `You are a creative writing assistant. Help with drafting, editing, and improving written content. Provide suggestions for style, tone, structure, and clarity. Offer multiple variations when appropriate. Focus on the user's voice and intent rather than web search results.`, }, FocusModeYouTube: { Mode: FocusModeYouTube, Engines: []string{"youtube"}, Categories: []string{"videos"}, SearchQueryPrefix: "site:youtube.com", MaxSources: 10, RequiresCitation: true, AllowScraping: false, SystemPrompt: `You are a video content assistant focused on YouTube. Summarize video content, recommend relevant videos, and help find tutorials. Mention video titles, channels, and approximate timestamps when relevant. Note view counts and upload dates to indicate video popularity and relevance.`, }, FocusModeReddit: { Mode: FocusModeReddit, Engines: []string{"reddit"}, Categories: []string{"social media"}, SearchQueryPrefix: "site:reddit.com", MaxSources: 15, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are an assistant that specializes in Reddit discussions and community knowledge. Focus on highly upvoted comments and posts from relevant subreddits. Note the subreddit source, upvote counts, and community consensus. Distinguish between personal opinions, experiences, and factual claims. Be aware of potential biases in specific communities.`, }, FocusModeCode: { Mode: FocusModeCode, Engines: []string{"google", "github", "stackoverflow"}, Categories: []string{"it"}, SearchQueryPrefix: "", MaxSources: 10, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are a programming assistant focused on code, documentation, and technical solutions. Provide working code examples with explanations. Reference official documentation, Stack Overflow answers, and GitHub repositories. Mention library versions and compatibility considerations. Follow best practices and coding standards for the relevant language/framework. Include error handling and edge cases in code examples.`, }, FocusModeNews: { Mode: FocusModeNews, Engines: []string{"google news", "bing news"}, Categories: []string{"news"}, MaxSources: 12, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are a news assistant that provides current events information. Focus on recent, verified news from reputable sources. Distinguish between breaking news, analysis, and opinion pieces. Note publication dates and source credibility. Present multiple perspectives on controversial topics.`, }, FocusModeImages: { Mode: FocusModeImages, Engines: []string{"google images", "bing images"}, Categories: []string{"images"}, MaxSources: 20, RequiresCitation: true, AllowScraping: false, SystemPrompt: `You are an image search assistant. Help find relevant images, describe image sources, and provide context. Note image sources, licenses, and quality when relevant.`, }, FocusModeMath: { Mode: FocusModeMath, Engines: []string{"wolfram alpha", "google"}, Categories: []string{"science"}, MaxSources: 5, RequiresCitation: true, AllowScraping: false, SystemPrompt: `You are a mathematical problem-solving assistant. Provide step-by-step solutions with clear explanations. Use proper mathematical notation and formatting. Show your work and explain the reasoning behind each step. Mention relevant theorems, formulas, and mathematical concepts. Verify your calculations and provide alternative solution methods when applicable.`, }, FocusModeFinance: { Mode: FocusModeFinance, Engines: []string{"google", "google finance", "yahoo finance"}, Categories: []string{"news"}, SearchQueryPrefix: "stock market finance", MaxSources: 10, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are a financial information assistant. Provide accurate financial data, market analysis, and investment information. Note that you cannot provide personalized financial advice. Cite data sources and note when data may be delayed or historical. Include relevant disclaimers about investment risks. Reference SEC filings, analyst reports, and official company statements.`, }, FocusModeTravel: { Mode: FocusModeTravel, Engines: []string{"google", "duckduckgo", "google news"}, Categories: []string{"general", "news"}, MaxSources: 15, RequiresCitation: true, AllowScraping: true, SystemPrompt: `You are a travel planning assistant. Help users plan trips with routes, accommodations, activities, and transport. Search for events, festivals, and attractions at destinations. Provide practical travel tips and budget estimates.`, }, } func GetFocusModeConfig(mode string) FocusModeConfig { fm := FocusMode(strings.ToLower(mode)) if cfg, ok := FocusModeConfigs[fm]; ok { return cfg } return FocusModeConfigs[FocusModeAll] } func DetectFocusMode(query string) FocusMode { queryLower := strings.ToLower(query) academicKeywords := []string{ "research", "paper", "study", "journal", "scientific", "academic", "peer-reviewed", "citation", "исследование", "научн", "статья", "публикация", "диссертация", } for _, kw := range academicKeywords { if strings.Contains(queryLower, kw) { return FocusModeAcademic } } codeKeywords := []string{ "code", "programming", "function", "error", "bug", "api", "library", "framework", "syntax", "compile", "debug", "код", "программ", "функция", "ошибка", "библиотека", "golang", "python", "javascript", "typescript", "react", "vue", "docker", "kubernetes", "sql", "database", "git", } for _, kw := range codeKeywords { if strings.Contains(queryLower, kw) { return FocusModeCode } } if strings.Contains(queryLower, "youtube") || strings.Contains(queryLower, "video tutorial") || strings.Contains(queryLower, "видео") { return FocusModeYouTube } if strings.Contains(queryLower, "reddit") || strings.Contains(queryLower, "subreddit") || strings.Contains(queryLower, "/r/") { return FocusModeReddit } mathKeywords := []string{ "calculate", "solve", "equation", "integral", "derivative", "formula", "theorem", "proof", "вычисл", "решить", "уравнение", "интеграл", "производная", "формула", "теорема", } for _, kw := range mathKeywords { if strings.Contains(queryLower, kw) { return FocusModeMath } } financeKeywords := []string{ "stock", "market", "invest", "price", "trading", "finance", "акци", "рынок", "инвест", "биржа", "котировк", "финанс", "etf", "dividend", "portfolio", } for _, kw := range financeKeywords { if strings.Contains(queryLower, kw) { return FocusModeFinance } } travelKeywords := []string{ "travel", "trip", "flight", "hotel", "vacation", "destination", "путешеств", "поездк", "маршрут", "отель", "перелёт", "перелет", "отдых", "тур", "куда поехать", "куда сходить", "достопримечательност", "мероприят", "билет", "бронирован", } for _, kw := range travelKeywords { if strings.Contains(queryLower, kw) { return FocusModeTravel } } newsKeywords := []string{ "news", "today", "latest", "breaking", "current events", "новост", "сегодня", "последн", "актуальн", } for _, kw := range newsKeywords { if strings.Contains(queryLower, kw) { return FocusModeNews } } return FocusModeAll } func (f FocusMode) GetSearchEngines() []string { if cfg, ok := FocusModeConfigs[f]; ok { return cfg.Engines } return FocusModeConfigs[FocusModeAll].Engines } func (f FocusMode) GetSystemPrompt() string { if cfg, ok := FocusModeConfigs[f]; ok { return cfg.SystemPrompt } return FocusModeConfigs[FocusModeAll].SystemPrompt } func (f FocusMode) GetMaxSources() int { if cfg, ok := FocusModeConfigs[f]; ok { return cfg.MaxSources } return 15 } func (f FocusMode) RequiresCitation() bool { if cfg, ok := FocusModeConfigs[f]; ok { return cfg.RequiresCitation } return true } func (f FocusMode) AllowsScraping() bool { if cfg, ok := FocusModeConfigs[f]; ok { return cfg.AllowScraping } return true } func EnhanceQueryForFocusMode(query string, mode FocusMode) string { cfg := FocusModeConfigs[mode] if cfg.SearchQueryPrefix != "" { return cfg.SearchQueryPrefix + " " + query } return query }