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

@@ -0,0 +1,57 @@
package travel
import (
"context"
"github.com/gooseek/backend/internal/llm"
)
type LLMClientAdapter struct {
client llm.Client
}
func NewLLMClientAdapter(client llm.Client) *LLMClientAdapter {
return &LLMClientAdapter{client: client}
}
func (a *LLMClientAdapter) StreamChat(ctx context.Context, messages []ChatMessage, onChunk func(string)) error {
llmMessages := make([]llm.Message, len(messages))
for i, m := range messages {
var role llm.Role
switch m.Role {
case "system":
role = llm.RoleSystem
case "user":
role = llm.RoleUser
case "assistant":
role = llm.RoleAssistant
default:
role = llm.RoleUser
}
llmMessages[i] = llm.Message{
Role: role,
Content: m.Content,
}
}
req := llm.StreamRequest{
Messages: llmMessages,
Options: llm.StreamOptions{
MaxTokens: 4096,
Temperature: 0.7,
},
}
ch, err := a.client.StreamText(ctx, req)
if err != nil {
return err
}
for chunk := range ch {
if chunk.ContentChunk != "" {
onChunk(chunk.ContentChunk)
}
}
return nil
}