Major changes: - Add Go backend (backend/) with microservices architecture - Enhanced master-agents-svc: reranker, content-classifier, stealth-crawler, proxy-manager, media-search, fastClassifier, language detection - New web-svc widgets: KnowledgeCard, ProductCard, ProfileCard, VideoCard, UnifiedCard, CardGallery, InlineImageGallery, SourcesPanel, RelatedQuestions - Improved discover-svc with discover-db integration - Docker deployment improvements (Caddyfile, vendor.sh, BUILD.md) - Library-svc: project_id schema migration - Remove deprecated finance-svc and travel-svc - Localization improvements across services Made-with: Cursor
294 lines
9.8 KiB
Go
294 lines
9.8 KiB
Go
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"
|
|
)
|
|
|
|
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.`,
|
|
},
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|