feat: travel service with 2GIS routing, POI, hotels + finance providers + UI overhaul

- Add travel-svc microservice (Amadeus, TravelPayouts, 2GIS, OpenRouteService)
- Add travel orchestrator with parallel collectors (events, POI, hotels, flights)
- Add 2GIS road routing with transport cost calculation (car/bus/taxi)
- Add TravelMap (2GIS MapGL) and TravelWidgets components
- Add useTravelChat hook for streaming travel agent responses
- Add finance heatmap providers refactor
- Add SearXNG settings, API proxy routes, Docker compose updates
- Update Dockerfiles, config, types, and all UI pages for consistency

Made-with: Cursor
This commit is contained in:
home
2026-03-01 21:58:32 +03:00
parent e6b9cfc60a
commit 08bd41e75c
71 changed files with 12364 additions and 945 deletions

View File

@@ -17,6 +17,7 @@ const (
FocusModeImages FocusMode = "images"
FocusModeMath FocusMode = "math"
FocusModeFinance FocusMode = "finance"
FocusModeTravel FocusMode = "travel"
)
type FocusModeConfig struct {
@@ -165,6 +166,18 @@ 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 {
@@ -236,6 +249,18 @@ func DetectFocusMode(query string) FocusMode {
}
}
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",
"новост", "сегодня", "последн", "актуальн",