Integrated AI summary

This commit is contained in:
Mazyar
2026-05-05 17:47:31 +03:30
parent ddbf1ca3d5
commit 65a19d1514
12 changed files with 989 additions and 11 deletions
+73
View File
@@ -3,6 +3,7 @@ package bootstrap
import (
"fmt"
"time"
ai_summarizer "tm/pkg/ai_summarizer"
"tm/pkg/authorization"
"tm/pkg/config"
"tm/pkg/filestore"
@@ -333,3 +334,75 @@ func InitFileStore(mongoManager *mongo.ConnectionManager, log logger.Logger) (*f
return fileStoreService, nil
}
// InitAISummarizerClient initializes the AI summarizer HTTP client for on-demand summarization
func InitAISummarizerClient(conf AISummarizerConfig, log logger.Logger) *ai_summarizer.Client {
if conf.APIBaseURL == "" {
log.Warn("AI Summarizer API base URL not configured, on-demand summarization will be unavailable", map[string]interface{}{})
return nil
}
cfg := &ai_summarizer.Config{
APIBaseURL: conf.APIBaseURL,
APITimeout: conf.APITimeout,
APIRetryCount: conf.APIRetryCount,
APIRetryDelay: conf.APIRetryDelay,
MinioEndpoint: conf.MinioEndpoint,
MinioAccessKey: conf.MinioAccessKey,
MinioSecretKey: conf.MinioSecretKey,
MinioUseSSL: conf.MinioUseSSL,
MinioRegion: conf.MinioRegion,
MinioBucket: conf.MinioBucket,
}
client, err := ai_summarizer.NewClient(cfg, log)
if err != nil {
log.Error("Failed to initialize AI Summarizer client", map[string]interface{}{
"error": err.Error(),
})
return nil
}
log.Info("AI Summarizer HTTP client initialized successfully", map[string]interface{}{
"base_url": conf.APIBaseURL,
"timeout": conf.APITimeout,
})
return client
}
// InitAISummarizerStorage initializes the AI summarizer MinIO storage client
func InitAISummarizerStorage(conf AISummarizerConfig, log logger.Logger) *ai_summarizer.StorageClient {
if conf.MinioEndpoint == "" {
log.Warn("AI Summarizer MinIO endpoint not configured, storage-based summaries will be unavailable", map[string]interface{}{})
return nil
}
cfg := &ai_summarizer.Config{
APIBaseURL: conf.APIBaseURL,
APITimeout: conf.APITimeout,
APIRetryCount: conf.APIRetryCount,
APIRetryDelay: conf.APIRetryDelay,
MinioEndpoint: conf.MinioEndpoint,
MinioAccessKey: conf.MinioAccessKey,
MinioSecretKey: conf.MinioSecretKey,
MinioUseSSL: conf.MinioUseSSL,
MinioRegion: conf.MinioRegion,
MinioBucket: conf.MinioBucket,
}
storage, err := ai_summarizer.NewStorageClient(cfg, log)
if err != nil {
log.Error("Failed to initialize AI Summarizer storage client", map[string]interface{}{
"error": err.Error(),
})
return nil
}
log.Info("AI Summarizer storage client initialized successfully", map[string]interface{}{
"endpoint": conf.MinioEndpoint,
"bucket": conf.MinioBucket,
})
return storage
}
+18
View File
@@ -22,6 +22,7 @@ type Config struct {
UserAuth AuthConfig
CustomerAuth AuthConfig
DocumentScraper DocumentScraperConfig
AISummarizer AISummarizerConfig
}
type GLMConfig struct {
@@ -88,3 +89,20 @@ type JWTConfig struct {
type DocumentScraperConfig struct {
APIKey string `env:"DOCUMENT_SCRAPER_API_KEY" envDefault:""`
}
// AISummarizerConfig holds configuration for the external AI summarizer service
type AISummarizerConfig struct {
// HTTP API settings
APIBaseURL string `env:"AI_SUMMARIZER_API_BASE_URL" envDefault:""`
APITimeout time.Duration `env:"AI_SUMMARIZER_API_TIMEOUT" envDefault:"120s"`
APIRetryCount int `env:"AI_SUMMARIZER_API_RETRY_COUNT" envDefault:"2"`
APIRetryDelay time.Duration `env:"AI_SUMMARIZER_API_RETRY_DELAY" envDefault:"3s"`
// MinIO storage settings
MinioEndpoint string `env:"AI_SUMMARIZER_MINIO_ENDPOINT" envDefault:""`
MinioAccessKey string `env:"AI_SUMMARIZER_MINIO_ACCESS_KEY" envDefault:""`
MinioSecretKey string `env:"AI_SUMMARIZER_MINIO_SECRET_KEY" envDefault:""`
MinioUseSSL bool `env:"AI_SUMMARIZER_MINIO_USE_SSL" envDefault:"false"`
MinioRegion string `env:"AI_SUMMARIZER_MINIO_REGION" envDefault:"us-east-1"`
MinioBucket string `env:"AI_SUMMARIZER_MINIO_BUCKET" envDefault:"opplens-documents"`
}
+12 -1
View File
@@ -162,6 +162,17 @@ func main() {
// Initialize GLM service
glmSDK := bootstrap.InitGLMService(conf.GLM, logger)
// Initialize AI Summarizer service
var aiSummarizerClient tender.AISummarizerClient
var aiSummarizerStorage tender.AISummarizerStorage
if c := bootstrap.InitAISummarizerClient(conf.AISummarizer, logger); c != nil {
aiSummarizerClient = c
}
if s := bootstrap.InitAISummarizerStorage(conf.AISummarizer, logger); s != nil {
aiSummarizerStorage = s
}
// Initialize authorization service
userAuthService := bootstrap.InitAuthorizationService(conf.UserAuth.JWT, redisClient, logger)
customerAuthService := bootstrap.InitAuthorizationService(conf.CustomerAuth.JWT, redisClient, logger)
@@ -196,7 +207,7 @@ func main() {
categoryService := company_category.NewService(categoryRepository, logger)
companyService := company.NewService(companyRepository, categoryService, logger)
customerService := customer.NewService(customerRepository, logger, customerAuthService, companyService, redisClient, notificationSDK, customerValidator, glmSDK)
tenderService := tender.NewService(tenderRepository, companyService, customerService, logger)
tenderService := tender.NewService(tenderRepository, companyService, customerService, logger, aiSummarizerClient, aiSummarizerStorage)
feedbackService := feedback.NewService(feedbackRepo, tenderService, companyService, logger)
tenderApprovalService := tender_approval.NewService(tenderApprovalRepository, tenderService, logger)
inquiryService := inquiry.NewService(inquiryRepository, notificationSDK, logger, xssPolicy)
+4
View File
@@ -105,9 +105,12 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
{
tendersGP.Use(userHandler.AuthMiddleware())
tendersGP.GET("", tenderHandler.Search)
tendersGP.GET("/ai-summaries", tenderHandler.GetAllAISummaries)
tendersGP.GET("/:id", tenderHandler.Get)
tendersGP.PUT("/:id", tenderHandler.Update)
tendersGP.DELETE("/:id", tenderHandler.Delete)
tendersGP.GET("/:id/ai-summary", tenderHandler.GetAISummary)
tendersGP.POST("/:id/ai-summarize", tenderHandler.TriggerAISummarize)
}
// Admin Feedback Routes
@@ -233,6 +236,7 @@ func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tende
tendersGP.GET("/recommend", tenderHandler.RecommendTenders)
tendersGP.GET("/details/:id", tenderHandler.GetPublicTenderDetails)
tendersGP.GET("/:id/document-summaries", tenderHandler.GetDocumentSummaries)
tendersGP.GET("/:id/ai-summary", tenderHandler.GetPublicAISummary)
}
// Public Feedback Routes