tender summary refactor
This commit is contained in:
@@ -156,6 +156,8 @@ func languageInDone(done []string, language string) bool {
|
|||||||
// TenderJSON represents the structure of the <notice_id>/tender.json file
|
// TenderJSON represents the structure of the <notice_id>/tender.json file
|
||||||
// stored in the AI service's MinIO bucket.
|
// stored in the AI service's MinIO bucket.
|
||||||
type TenderJSON struct {
|
type TenderJSON struct {
|
||||||
|
// Summary is the current pipeline field for the tender-level summary text.
|
||||||
|
Summary string `json:"summary"`
|
||||||
OverallSummary *string `json:"overall_summary"`
|
OverallSummary *string `json:"overall_summary"`
|
||||||
OverallSummaryCamel *string `json:"overallSummary"`
|
OverallSummaryCamel *string `json:"overallSummary"`
|
||||||
SummarizeStatus SummarizeStatus `json:"summarize_status"`
|
SummarizeStatus SummarizeStatus `json:"summarize_status"`
|
||||||
@@ -165,16 +167,30 @@ type TenderJSON struct {
|
|||||||
TranslationStatusCamel TranslationStatus `json:"translationStatus"`
|
TranslationStatusCamel TranslationStatus `json:"translationStatus"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolved returns whether summarization is marked done and the best-effort
|
// summaryText returns the best-effort tender-level summary (may be empty).
|
||||||
// overall summary pointer (may be nil or empty when the pipeline finished
|
func (t *TenderJSON) summaryText() string {
|
||||||
// without text yet).
|
if t == nil {
|
||||||
func (t *TenderJSON) resolved() (done bool, overall *string) {
|
return ""
|
||||||
done = t.SummarizeStatus.isDone() || t.SummarizeStatusCamel.isDone()
|
|
||||||
overall = t.OverallSummary
|
|
||||||
if overall == nil || strings.TrimSpace(*overall) == "" {
|
|
||||||
overall = t.OverallSummaryCamel
|
|
||||||
}
|
}
|
||||||
return done, overall
|
for _, candidate := range []*string{t.OverallSummary, t.OverallSummaryCamel} {
|
||||||
|
if candidate == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if text := strings.TrimSpace(*candidate); text != "" {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(t.Summary)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolved returns whether summarization is marked done and the summary text
|
||||||
|
// (may be empty when the pipeline finished without text yet).
|
||||||
|
func (t *TenderJSON) resolved() (done bool, overall string) {
|
||||||
|
if t == nil {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
done = t.SummarizeStatus.isDone() || t.SummarizeStatusCamel.isDone()
|
||||||
|
return done, t.summaryText()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SummarizeStatus represents the summarization status inside tender.json.
|
// SummarizeStatus represents the summarization status inside tender.json.
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ var (
|
|||||||
ErrSummaryNotReady = errors.New("ai_summarizer: summary not ready yet")
|
ErrSummaryNotReady = errors.New("ai_summarizer: summary not ready yet")
|
||||||
|
|
||||||
// ErrNoOverallSummary is returned when the pipeline is done but
|
// ErrNoOverallSummary is returned when the pipeline is done but
|
||||||
// overall_summary is empty or null.
|
// summary / overall_summary text is empty.
|
||||||
ErrNoOverallSummary = errors.New("ai_summarizer: overall_summary is empty")
|
ErrNoOverallSummary = errors.New("ai_summarizer: tender summary is empty")
|
||||||
|
|
||||||
// ErrTranslationNotReady is returned when tender.json exists but the
|
// ErrTranslationNotReady is returned when tender.json exists but the
|
||||||
// requested language is not listed in translation_status.done yet.
|
// requested language is not listed in translation_status.done yet.
|
||||||
|
|||||||
@@ -278,13 +278,15 @@ func (s *StorageClient) resolveNoticeStoragePrefix(ctx context.Context, contract
|
|||||||
|
|
||||||
// GetSummaryFromStorage fetches the
|
// GetSummaryFromStorage fetches the
|
||||||
// PROC_<contractFolderID>/<noticePublicationID>/tender.json file from the AI
|
// PROC_<contractFolderID>/<noticePublicationID>/tender.json file from the AI
|
||||||
// service's MinIO bucket, parses it, and returns the overall_summary string.
|
// service's MinIO bucket, parses it, and returns the tender summary text.
|
||||||
|
//
|
||||||
|
// Summary text is read from summary (current) or overall_summary (legacy).
|
||||||
//
|
//
|
||||||
// It returns:
|
// It returns:
|
||||||
// - (summary, nil) on success
|
// - (summary, nil) on success
|
||||||
// - ("", ErrObjectNotFound) if the tender.json does not exist (404)
|
// - ("", ErrObjectNotFound) if the tender.json does not exist (404)
|
||||||
// - ("", ErrSummaryNotReady) if the file exists but summarize_status.done is false
|
// - ("", ErrSummaryNotReady) if the file exists but summarize_status.done is false
|
||||||
// - ("", ErrNoOverallSummary) if done is true but overall_summary is empty/null
|
// - ("", ErrNoOverallSummary) if done is true but summary text is empty
|
||||||
// - ("", error) for any other failure
|
// - ("", error) for any other failure
|
||||||
func (s *StorageClient) GetSummaryFromStorage(ctx context.Context, contractFolderID, noticePublicationID string) (string, error) {
|
func (s *StorageClient) GetSummaryFromStorage(ctx context.Context, contractFolderID, noticePublicationID string) (string, error) {
|
||||||
if strings.TrimSpace(contractFolderID) == "" {
|
if strings.TrimSpace(contractFolderID) == "" {
|
||||||
@@ -352,7 +354,7 @@ func (s *StorageClient) getTranslationFromObjectKey(ctx context.Context, objectK
|
|||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSummaryFromObjectKey reads tender.json at objectKey and returns overall_summary when ready.
|
// getSummaryFromObjectKey reads tender.json at objectKey and returns summary text when ready.
|
||||||
// contractFolderID and noticePublicationID are used for logging only (may be empty when unknown).
|
// contractFolderID and noticePublicationID are used for logging only (may be empty when unknown).
|
||||||
func (s *StorageClient) readTenderJSONAtKey(ctx context.Context, objectKey string) (*TenderJSON, error) {
|
func (s *StorageClient) readTenderJSONAtKey(ctx context.Context, objectKey string) (*TenderJSON, error) {
|
||||||
object, err := s.client.GetObject(ctx, s.config.MinioBucket, objectKey, minio.GetObjectOptions{})
|
object, err := s.client.GetObject(ctx, s.config.MinioBucket, objectKey, minio.GetObjectOptions{})
|
||||||
@@ -403,17 +405,15 @@ func (s *StorageClient) getSummaryFromObjectKey(ctx context.Context, objectKey,
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
done, overall := tenderJSON.resolved()
|
done, summaryText := tenderJSON.resolved()
|
||||||
if !done {
|
if !done {
|
||||||
return "", ErrSummaryNotReady
|
return "", ErrSummaryNotReady
|
||||||
}
|
}
|
||||||
if overall == nil || strings.TrimSpace(*overall) == "" {
|
if summaryText == "" {
|
||||||
return "", ErrNoOverallSummary
|
return "", ErrNoOverallSummary
|
||||||
}
|
}
|
||||||
|
|
||||||
summaryText := strings.TrimSpace(*overall)
|
s.logger.Info("Retrieved tender summary from storage", map[string]interface{}{
|
||||||
|
|
||||||
s.logger.Info("Retrieved overall_summary from storage", map[string]interface{}{
|
|
||||||
"contract_folder_id": contractFolderID,
|
"contract_folder_id": contractFolderID,
|
||||||
"notice_id": noticePublicationID,
|
"notice_id": noticePublicationID,
|
||||||
"object_key": objectKey,
|
"object_key": objectKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user