feat: save prompt caption alongside every generated image
After each successful image upload to storage, a sidecar `.caption`
file is uploaded at the same path with `.caption` extension containing
the exact prompt used to generate the image.
Coverage:
- generation/handlers.go: ImageHandler → media/{userID}/images/{jobID}_{i}.caption
- album/handler.go: AnchorHandler → albums/{userID}/{albumID}/anchor.caption
- album/handler.go: ShotHandler → albums/{userID}/{albumID}/shots/{shotIndex}.caption
- personagen/service.go: generatePosition → personas/{specID}/images/{pos:02d}.caption
Caption failures are logged at warn level and never abort the job.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3979ef2d08
commit
062a828a00
@ -83,6 +83,10 @@ func AnchorHandler(mg *mediagen.Manager, store storage.Store, pub realtime.Event
|
||||
logger.Warn("failed to persist anchor to storage, using inline URL", "error", uploadErr, "job_id", job.ID)
|
||||
} else {
|
||||
anchorURL = url
|
||||
captionPath := fmt.Sprintf("albums/%s/%s/anchor.caption", userID, albumID)
|
||||
if _, captionErr := store.Upload(ctx, captionPath, []byte(subjectDesc), "text/plain"); captionErr != nil {
|
||||
logger.Warn("failed to persist anchor caption", "error", captionErr, "job_id", job.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,6 +217,10 @@ func ShotHandler(mg *mediagen.Manager, store storage.Store, pub realtime.EventPu
|
||||
"error", uploadErr, "job_id", job.ID)
|
||||
} else {
|
||||
imageURL = url
|
||||
captionPath := fmt.Sprintf("albums/%s/%s/shots/%d.caption", userID, albumID, shotIndex)
|
||||
if _, captionErr := store.Upload(ctx, captionPath, []byte(prompt), "text/plain"); captionErr != nil {
|
||||
logger.Warn("failed to persist shot caption", "error", captionErr, "job_id", job.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +100,10 @@ func ImageHandler(mg *mediagen.Manager, store storage.Store, pub realtime.EventP
|
||||
if uploadErr != nil {
|
||||
logger.Warn("failed to persist image to storage", "error", uploadErr, "job_id", job.ID)
|
||||
} else {
|
||||
captionPath := fmt.Sprintf("media/%s/images/%s_%d.caption", userID, job.ID, i)
|
||||
if _, captionErr := store.Upload(ctx, captionPath, []byte(prompt), "text/plain"); captionErr != nil {
|
||||
logger.Warn("failed to persist image caption", "error", captionErr, "job_id", job.ID)
|
||||
}
|
||||
images[i] = GeneratedImage{Data: url, IsURL: true, Seed: resp.Seed}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -228,6 +228,13 @@ func (s *Service) generatePosition(ctx context.Context, spec *persona.PersonaSpe
|
||||
return fmt.Errorf("storing position %d: %w", pos, err)
|
||||
}
|
||||
|
||||
if imgSpec.Prompt != "" {
|
||||
captionPath := fmt.Sprintf("personas/%s/images/%02d.caption", spec.ID, pos)
|
||||
if _, captionErr := s.store.Upload(ctx, captionPath, []byte(imgSpec.Prompt), "text/plain"); captionErr != nil {
|
||||
s.logger.Warn("failed to persist image caption", "error", captionErr, "position", pos)
|
||||
}
|
||||
}
|
||||
|
||||
imgSpec.URL = url
|
||||
imgSpec.Status = persona.ImageStatusComplete
|
||||
return nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user