feat: Go backend, enhanced search, new widgets, Docker deploy

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
This commit is contained in:
home
2026-02-27 04:15:32 +03:00
parent 328d968f3f
commit 06fe57c765
285 changed files with 53132 additions and 1871 deletions

View File

@@ -0,0 +1,102 @@
package types
type BlockType string
const (
BlockTypeText BlockType = "text"
BlockTypeResearch BlockType = "research"
BlockTypeSource BlockType = "source"
BlockTypeWidget BlockType = "widget"
BlockTypeThinking BlockType = "thinking"
)
type Block struct {
ID string `json:"id"`
Type BlockType `json:"type"`
Data interface{} `json:"data"`
}
type TextBlock struct {
ID string `json:"id"`
Type string `json:"type"`
Data string `json:"data"`
}
type ResearchBlock struct {
ID string `json:"id"`
Type string `json:"type"`
Data ResearchData `json:"data"`
}
type ResearchData struct {
SubSteps []ResearchSubStep `json:"subSteps"`
}
type ResearchSubStep struct {
ID string `json:"id"`
Type string `json:"type"`
Reasoning string `json:"reasoning,omitempty"`
Searching []string `json:"searching,omitempty"`
Reading []Chunk `json:"reading,omitempty"`
}
type SourceBlock struct {
ID string `json:"id"`
Type string `json:"type"`
Data []Chunk `json:"data"`
}
type WidgetBlock struct {
ID string `json:"id"`
Type string `json:"type"`
Data WidgetData `json:"data"`
}
type WidgetData struct {
WidgetType string `json:"widgetType"`
Params interface{} `json:"params"`
}
type StreamEvent struct {
Type string `json:"type"`
Block *Block `json:"block,omitempty"`
BlockID string `json:"blockId,omitempty"`
Chunk string `json:"chunk,omitempty"`
Patch interface{} `json:"patch,omitempty"`
Data interface{} `json:"data,omitempty"`
}
func NewTextBlock(id, content string) *Block {
return &Block{
ID: id,
Type: BlockTypeText,
Data: content,
}
}
func NewResearchBlock(id string) *Block {
return &Block{
ID: id,
Type: BlockTypeResearch,
Data: ResearchData{SubSteps: []ResearchSubStep{}},
}
}
func NewSourceBlock(id string, chunks []Chunk) *Block {
return &Block{
ID: id,
Type: BlockTypeSource,
Data: chunks,
}
}
func NewWidgetBlock(id, widgetType string, params interface{}) *Block {
return &Block{
ID: id,
Type: BlockTypeWidget,
Data: WidgetData{
WidgetType: widgetType,
Params: params,
},
}
}

View File

@@ -0,0 +1,75 @@
package types
type Chunk struct {
Content string `json:"content"`
Metadata map[string]string `json:"metadata,omitempty"`
}
type SearchResult struct {
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content,omitempty"`
Thumbnail string `json:"thumbnail,omitempty"`
ImgSrc string `json:"img_src,omitempty"`
ThumbnailSrc string `json:"thumbnail_src,omitempty"`
IframeSrc string `json:"iframe_src,omitempty"`
Author string `json:"author,omitempty"`
PublishedDate string `json:"publishedDate,omitempty"`
Engine string `json:"engine,omitempty"`
Category string `json:"category,omitempty"`
Score float64 `json:"score,omitempty"`
Price string `json:"price,omitempty"`
Currency string `json:"currency,omitempty"`
Duration interface{} `json:"duration,omitempty"`
Views interface{} `json:"views,omitempty"`
}
type SearchResponse struct {
Results []SearchResult `json:"results"`
Suggestions []string `json:"suggestions,omitempty"`
}
type ContentCategory string
const (
CategoryProduct ContentCategory = "product"
CategoryVideo ContentCategory = "video"
CategoryProfile ContentCategory = "profile"
CategoryPromo ContentCategory = "promo"
CategoryImage ContentCategory = "image"
CategoryArticle ContentCategory = "article"
)
func (r *SearchResult) ToChunk() Chunk {
metadata := map[string]string{
"title": r.Title,
"url": r.URL,
}
if r.Thumbnail != "" {
metadata["thumbnail"] = r.Thumbnail
}
if r.Author != "" {
metadata["author"] = r.Author
}
if r.PublishedDate != "" {
metadata["publishedDate"] = r.PublishedDate
}
content := r.Content
if content == "" {
content = r.Title
}
return Chunk{
Content: content,
Metadata: metadata,
}
}
func SearchResultsToChunks(results []SearchResult) []Chunk {
chunks := make([]Chunk, 0, len(results))
for _, r := range results {
chunks = append(chunks, r.ToChunk())
}
return chunks
}

View File

@@ -0,0 +1,145 @@
package types
type WidgetType string
const (
WidgetWeather WidgetType = "weather"
WidgetCalculator WidgetType = "calculator"
WidgetProducts WidgetType = "products"
WidgetVideos WidgetType = "videos"
WidgetProfiles WidgetType = "profiles"
WidgetPromos WidgetType = "promos"
WidgetImageGallery WidgetType = "image_gallery"
WidgetVideoEmbed WidgetType = "video_embed"
WidgetKnowledge WidgetType = "knowledge_card"
)
type ProductData struct {
Title string `json:"title"`
URL string `json:"url"`
Price float64 `json:"price"`
OldPrice float64 `json:"oldPrice,omitempty"`
Currency string `json:"currency"`
Discount int `json:"discount,omitempty"`
Rating float64 `json:"rating,omitempty"`
ReviewCount int `json:"reviewCount,omitempty"`
ImageURL string `json:"imageUrl,omitempty"`
Marketplace string `json:"marketplace"`
InStock bool `json:"inStock"`
Badges []Badge `json:"badges,omitempty"`
}
type VideoData struct {
Title string `json:"title"`
URL string `json:"url"`
Thumbnail string `json:"thumbnail,omitempty"`
Duration int `json:"duration,omitempty"`
Views int `json:"views,omitempty"`
Likes int `json:"likes,omitempty"`
Author string `json:"author,omitempty"`
Platform string `json:"platform"`
EmbedURL string `json:"embedUrl,omitempty"`
}
type ProfileData struct {
Name string `json:"name"`
Username string `json:"username,omitempty"`
URL string `json:"url"`
AvatarURL string `json:"avatarUrl,omitempty"`
Bio string `json:"bio,omitempty"`
Followers int `json:"followers,omitempty"`
Following int `json:"following,omitempty"`
Platform string `json:"platform"`
Verified bool `json:"verified"`
IsOnline bool `json:"isOnline,omitempty"`
LastOnline string `json:"lastOnline,omitempty"`
}
type PromoData struct {
Code string `json:"code"`
Description string `json:"description"`
Discount string `json:"discount"`
Store string `json:"store"`
StoreURL string `json:"storeUrl"`
LogoURL string `json:"logoUrl,omitempty"`
ExpiresAt string `json:"expiresAt,omitempty"`
Conditions string `json:"conditions,omitempty"`
Verified bool `json:"verified"`
}
type ImageData struct {
URL string `json:"url"`
Title string `json:"title,omitempty"`
Source string `json:"source,omitempty"`
SourceURL string `json:"sourceUrl,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
}
type Badge struct {
Text string `json:"text"`
Type string `json:"type"`
Color string `json:"color,omitempty"`
}
type KnowledgeCardData struct {
Type string `json:"type"`
Title string `json:"title,omitempty"`
Content interface{} `json:"content"`
}
type ComparisonTable struct {
Headers []string `json:"headers"`
Rows [][]string `json:"rows"`
}
type StatCard struct {
Label string `json:"label"`
Value string `json:"value"`
Change float64 `json:"change,omitempty"`
Unit string `json:"unit,omitempty"`
}
type Timeline struct {
Events []TimelineEvent `json:"events"`
}
type TimelineEvent struct {
Date string `json:"date"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
}
type WeatherParams struct {
Location string `json:"location"`
Current WeatherCurrent `json:"current"`
Forecast []WeatherDay `json:"forecast,omitempty"`
LastUpdated string `json:"lastUpdated,omitempty"`
}
type WeatherCurrent struct {
Temp float64 `json:"temp"`
FeelsLike float64 `json:"feelsLike"`
Humidity int `json:"humidity"`
WindSpeed float64 `json:"windSpeed"`
Description string `json:"description"`
Icon string `json:"icon"`
}
type WeatherDay struct {
Date string `json:"date"`
TempMax float64 `json:"tempMax"`
TempMin float64 `json:"tempMin"`
Icon string `json:"icon"`
}
type CalculatorParams struct {
Expression string `json:"expression"`
Result float64 `json:"result"`
Steps []Step `json:"steps,omitempty"`
}
type Step struct {
Description string `json:"description"`
Value string `json:"value"`
}