Repository navigation
Enrich books and products once, from their text plus the cover - #705
Merged
Merged
Conversation
A book or product with a cover queued enrich-item (text) and analyze-image together, and analyze-image queued a second enrich-item from the cover. Tags and the text vector are last-writer-wins, so the cover pass usually replaced the text one, and the first tag generation and embedding were wasted. Now a cover-bearing book or product queues only analyze-image, which takes the item's text as extraSourceText and blends it with the cover's objects and OCR (as analyze-media-cover does for tweets). A cover-less one enriches from its text alone. analyze-image's catch no longer turns a completed item failed, matching enrich-item and analyze-media-cover. Amp-Thread-ID: https://ampcode.com/threads/T-01a1daa2-36bf-7085-8fc3-5fd53d723953
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
6 tasks done
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
- A book or product's enrichment now generates its tags from the item's text blended with the cover, instead of the cover's vision tags alone. - The cover's objects/OCR lead the blend, so a long description is what the token limit cuts. - Once a cover analysis has failed for good, analyze-image's onFailure enriches the item from its text, so a failed cover doesn't leave it without tags. Amp-Thread-ID: https://ampcode.com/threads/T-01a1daa2-36bf-7085-8fc3-5fd53d723953
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
A re-capture replaces the cover and deletes the old one, so an older analyze-image run then fails; its text fallback would re-enrich the item from the old capture's text over the newer run's. Only fall back while the run's cover is still the item's cover. Amp-Thread-ID: https://ampcode.com/threads/T-01a1daa2-36bf-7085-8fc3-5fd53d723953
fredrivett
pushed a commit
that referenced
this pull request
Nov 14, 2026
Merges fredrivett/single-cover-enrichment (analyze-image's text fallback once its cover has failed for good), keeping that fallback alongside the shared failure hooks: analyze-image reports the error and enriches from the item's text instead of marking it failed when the run carried item text. From cubic's review of #706: - itemFailureHooks always leaves a completed item as it is. User-initiated runs set the item to processing first, so a completed item means a later stage or a background re-run (admin reprocess, cover swap) failed; the keepCompleted option is gone. - Failure reports carry the payload's url/fileKey again. - isPermanentFailure treats every SafeFetchError (redirect cap, invalid redirect, oversized body) as permanent. - import-pdf's upload-failure test checks catchError on the error run threw. Amp-Thread-ID: https://ampcode.com/threads/T-01a1daa2-36bf-7085-8fc3-5fd53d723953
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
The stale-run guard compared the run's fileKey with coverFileKey, so a product cover picked through PATCH (which queues no enrichment) skipped the text fallback and left the item without tags. Skip it only when the run's file is no longer one of the item's captured files, which is what a re-capture does.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
A book or product saved with a cover was enriched twice.
classify-urlqueuedenrich-item(from the title and description) andanalyze-image(the cover) together, andanalyze-imagethen queued a secondenrich-itembuilt only from the cover's objects and OCR. Tags and the text vector are last-writer-wins, so the cover pass usually won: a product's search vector came from its cover image rather than its title and description, and the first tag generation and embedding were wasted spend.analyze-image, which takes the item's text asextraSourceTextand blends it with the cover's objects and OCR — the same approachanalyze-media-coveralready takes for tweets (see the comment inhandle-twitter-url.ts). A book or product without a cover enriches from its text alone, as before.enrich-itemgenerates the tags from the blend (one gpt-4o-mini call, the same as the text-only enrich this removes) instead of taking the cover's vision tags alone. The cover's objects and OCR lead the blend, so a long description is what the token limit cuts. A plain image upload still uses its vision tags.analyze-image'sonFailureenriches the item from its text and the item still completes. It skips that fallback when a re-capture has since replaced the cover.analyze-image's catch now only marks an item failed if it hasn't completed, likeenrich-itemandanalyze-media-cover, so a cover-analysis failure (e.g. on reprocess) can't turn a finished item "Failed".Checklist
.env.example, in-app help,CONTRIBUTING.md, onboarding checklist), or N/A — N/A: no feature, service or setup changecaptureServerException/ the error boundary, or N/A — N/A: no new error pathsclassify-url.test.ts(one enrichment per product with a cover, blending its text; text-only for a book without one) and a newanalyze-image.integration.test.tsagainst real Postgres (blended source text and tags; vision tags kept for plain images; the text fallback, and its skip for a replaced cover; a failure never regresses a completed item)record-pr-demoskill); refactor through a user flow → parity run, or N/A — N/A: the change is inside the Trigger.dev pipeline, which isn't configured in the demo stack, so there's nothing to record; the visible effect is in tags and search resultslearnskill, or N/A — considered: the one-enrichment-per-save rule is now documented onanalyze-imageand the newtriggerEnrichmenthelper; no deterministic check fits a "don't queue both" rule without over-fittingNotes
bun run check:fixclean; the full unit suite passes.