AI translate refactor
This commit is contained in:
@@ -517,7 +517,8 @@ type AITranslateRequest struct {
|
||||
|
||||
// AITranslateResponse represents the response for AI translation trigger.
|
||||
type AITranslateResponse struct {
|
||||
NoticeID string `json:"notice_id"`
|
||||
ContractFolderID string `json:"contract_folder_id"`
|
||||
NoticePublicationID string `json:"notice_publication_id"`
|
||||
Language string `json:"language"`
|
||||
TranslatedTitle string `json:"translated_title"`
|
||||
TranslatedDescription string `json:"translated_description"`
|
||||
|
||||
+60
-33
@@ -21,6 +21,7 @@ import (
|
||||
type AISummarizerClient interface {
|
||||
FetchSummaryOnDemand(ctx context.Context, reqBody ai_summarizer.SummarizeRequest) (*ai_summarizer.SummarizeResponse, error)
|
||||
FetchTranslationOnDemand(ctx context.Context, reqBody ai_summarizer.TranslateRequest) (*ai_summarizer.TranslateResponse, error)
|
||||
TriggerPipelineTranslate(ctx context.Context, languages []string) (*ai_summarizer.PipelineTranslateResponse, error)
|
||||
}
|
||||
|
||||
// AISummarizerStorage defines the interface for fetching summaries from MinIO storage.
|
||||
@@ -28,6 +29,7 @@ type AISummarizerClient interface {
|
||||
// PROC_<contractFolderID>/<noticePublicationID>/ in the shared bucket.
|
||||
type AISummarizerStorage interface {
|
||||
GetSummaryFromStorage(ctx context.Context, contractFolderID, noticePublicationID string) (string, error)
|
||||
GetTranslationFromStorage(ctx context.Context, contractFolderID, noticePublicationID, language string) (ai_summarizer.StoredTranslation, error)
|
||||
ListDocuments(ctx context.Context, contractFolderID, noticePublicationID string) ([]ai_summarizer.StoredDocument, error)
|
||||
DownloadDocument(ctx context.Context, objectName string) (io.ReadCloser, error)
|
||||
}
|
||||
@@ -1051,25 +1053,13 @@ func (s *tenderService) TriggerAITranslate(ctx context.Context, id, language str
|
||||
return nil, fmt.Errorf("tender has no contract folder ID")
|
||||
}
|
||||
|
||||
if tr, ok := t.Translations[targetLanguage]; ok {
|
||||
return &AITranslateResponse{
|
||||
NoticeID: t.NoticePublicationID,
|
||||
Language: targetLanguage,
|
||||
TranslatedTitle: tr.Title,
|
||||
TranslatedDescription: tr.Description,
|
||||
}, nil
|
||||
if tr, ok := t.Translations[targetLanguage]; ok && strings.TrimSpace(tr.Title) != "" {
|
||||
return s.buildAITranslateResponse(t, targetLanguage, tr.Title, tr.Description), nil
|
||||
}
|
||||
|
||||
resp, err := s.aiSummarizerClient.FetchTranslationOnDemand(ctx, ai_summarizer.TranslateRequest{
|
||||
NoticeID: t.NoticePublicationID,
|
||||
ContractFolderID: t.ContractFolderID,
|
||||
NoticePublicationID: t.NoticePublicationID,
|
||||
Title: t.Title,
|
||||
Description: t.Description,
|
||||
Language: targetLanguage,
|
||||
})
|
||||
title, description, err := s.resolveTranslation(ctx, t, targetLanguage)
|
||||
if err != nil {
|
||||
s.logger.Error("On-demand AI translation failed", map[string]interface{}{
|
||||
s.logger.Error("AI translation failed", map[string]interface{}{
|
||||
"tender_id": id,
|
||||
"notice_id": t.NoticePublicationID,
|
||||
"language": targetLanguage,
|
||||
@@ -1078,33 +1068,70 @@ func (s *tenderService) TriggerAITranslate(ctx context.Context, id, language str
|
||||
return nil, fmt.Errorf("AI translation request failed: %w", err)
|
||||
}
|
||||
|
||||
s.storeTranslation(t, targetLanguage, title, description)
|
||||
if err := s.repository.Update(ctx, t); err != nil {
|
||||
return nil, fmt.Errorf("failed to persist translation: %w", err)
|
||||
}
|
||||
|
||||
return s.buildAITranslateResponse(t, targetLanguage, title, description), nil
|
||||
}
|
||||
|
||||
func (s *tenderService) buildAITranslateResponse(t *Tender, language, title, description string) *AITranslateResponse {
|
||||
return &AITranslateResponse{
|
||||
ContractFolderID: t.ContractFolderID,
|
||||
NoticePublicationID: t.NoticePublicationID,
|
||||
Language: language,
|
||||
TranslatedTitle: title,
|
||||
TranslatedDescription: description,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *tenderService) resolveTranslation(ctx context.Context, t *Tender, language string) (string, string, error) {
|
||||
if s.aiSummarizerStorage != nil {
|
||||
stored, err := s.aiSummarizerStorage.GetTranslationFromStorage(ctx, t.ContractFolderID, t.NoticePublicationID, language)
|
||||
if err == nil {
|
||||
return stored.Title, stored.Description, nil
|
||||
}
|
||||
if !errors.Is(err, ai_summarizer.ErrTranslationNotReady) &&
|
||||
!errors.Is(err, ai_summarizer.ErrObjectNotFound) &&
|
||||
!errors.Is(err, ai_summarizer.ErrNoTranslation) {
|
||||
s.logger.Debug("Translation not available from storage", map[string]interface{}{
|
||||
"tender_id": t.ID.Hex(),
|
||||
"language": language,
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := s.aiSummarizerClient.FetchTranslationOnDemand(ctx, ai_summarizer.TranslateRequest{
|
||||
ContractFolderID: t.ContractFolderID,
|
||||
NoticePublicationID: t.NoticePublicationID,
|
||||
Title: t.Title,
|
||||
Description: t.Description,
|
||||
Language: language,
|
||||
})
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return resp.TranslatedTitle, resp.TranslatedDescription, nil
|
||||
}
|
||||
|
||||
func (s *tenderService) storeTranslation(t *Tender, language, title, description string) {
|
||||
if t.Translations == nil {
|
||||
t.Translations = make(map[string]TranslationEntry)
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
t.Translations[targetLanguage] = TranslationEntry{
|
||||
Title: resp.TranslatedTitle,
|
||||
Description: resp.TranslatedDescription,
|
||||
Language: targetLanguage,
|
||||
t.Translations[language] = TranslationEntry{
|
||||
Title: title,
|
||||
Description: description,
|
||||
Language: language,
|
||||
TranslatedAt: now,
|
||||
}
|
||||
if t.ProcessingMetadata.TranslatedData == nil {
|
||||
t.ProcessingMetadata.TranslatedData = make(map[string]string)
|
||||
}
|
||||
t.ProcessingMetadata.TranslatedData[targetLanguage] = "done"
|
||||
t.ProcessingMetadata.TranslatedData[language] = "done"
|
||||
t.ProcessingMetadata.TranslatedAt = now
|
||||
|
||||
if err := s.repository.Update(ctx, t); err != nil {
|
||||
return nil, fmt.Errorf("failed to persist translation: %w", err)
|
||||
}
|
||||
|
||||
return &AITranslateResponse{
|
||||
NoticeID: resp.NoticeID,
|
||||
Language: targetLanguage,
|
||||
TranslatedTitle: resp.TranslatedTitle,
|
||||
TranslatedDescription: resp.TranslatedDescription,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *tenderService) pickResponseLanguage(language *string) string {
|
||||
|
||||
Reference in New Issue
Block a user