Cache only text reads that could name a product

The per-track OCR cache kept any non-empty read, so a first crop that read
only a size ("400g") was replayed on every later attempt. A size matches every
400g product's size line, so the track could never be named even after a clean
crop arrived: the cached read replaced it. Only a read carrying identity text
is cached now, so the next attempt gets a fresh OCR.

`carries_identity` moves to module scope in live.py; a function-local import
shadowed the name at the cache site and raised UnboundLocalError.
This commit is contained in:
tngo 2026-09-29 00:41:52 +09:00
parent b6c7c4b667
commit fc49ba60e6
2 changed files with 30 additions and 3 deletions

View file

@ -39,6 +39,7 @@ from engine import ( # noqa: E402
STATE_UNRECOGNIZED,
RecognitionEngine,
)
from identity_lanes import carries_identity # noqa: E402
from tracking import SessionTracker # noqa: E402
EMPTY_SLOT_HISTORY = 5
@ -1183,9 +1184,12 @@ class LiveSession:
self._classify_times.append(finished_at - submitted_at)
# The reading is cached on the track so later attempts skip OCR.
# An empty read is not cached: a crop that was too small or too
# blurry to read says nothing about the next one.
if text_read:
# Only a read that could name something is cached: a crop that was
# too small or too blurry says nothing about the next one, and a
# read of just a size ("400g") matches every 400g product's size
# line, so caching it would let one unreadable crop veto the
# product for the rest of the track's life.
if text_read and carries_identity(text_read):
track.text_rank = list(text_rank or [])
track.text_read = text_read
elif track.text_read: