Audit fixes: mis-framed crops, GPT cost 2.2x low, camera button losing photos
1. detail_crops had no equivalent of the margin guard the measurements got. When box detection fails (card still in a case), every crop is cut relative to the wrong rectangle -- verified the 'TOP-LEFT CORNER' close-up of the cased Ohtani is actually the CASE's corner bracket. The measurements refuse and explain; the crops kept being produced and captioned authoritatively, and the prompt tells the model to judge corners/edges/surface *from* them. Now surfaces a framing caveat telling the model to locate the real card edge inside each crop and say cannot_assess rather than grade the holder. 2. gpt-5.6-sol's approx_image_tokens was a pre-launch guess (1500) that advertised ~2.2x under true cost across all 9 real calls. Recalibrated to 3560 against median real usage, and added a per-model output estimate since GPT writes ~1.2k tokens of verdict vs Sonnet's ~0.9k. Both models now advertise within ~3% of observed cost. 3. 'Take photo' didn't reset after a completed grade, unlike 'Choose from library'. The result view has no photo strip, so new photos piled up invisibly behind the old verdict, silently, to the 6-photo cap. Also fixed the cap itself being a silent no-op with no explanation.
This commit is contained in:
parent
deabe74593
commit
6c612c1f4a
3 changed files with 79 additions and 12 deletions
|
|
@ -330,9 +330,22 @@ function resetGradeState() {
|
|||
renderGradeReview();
|
||||
}
|
||||
|
||||
// Matches MAX_GRADE_IMAGES in app.py — the server rejects more than this,
|
||||
// so the UI has to stop at the same number rather than let someone pick a
|
||||
// seventh photo and only find out when grading fails.
|
||||
const MAX_PHOTOS = 6;
|
||||
|
||||
async function addPickedFrom(input) {
|
||||
const room = MAX_PHOTOS - gradeState.files.length;
|
||||
if (room <= 0) {
|
||||
// Was a silent no-op: readPickedImages would slice to nothing and
|
||||
// return an empty array, so the tap did nothing with no explanation.
|
||||
banner(`That's the ${MAX_PHOTOS}-photo limit for one card — remove one, or grade these.`, true);
|
||||
input.value = '';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const picked = await readPickedImages(input, 6 - gradeState.files.length);
|
||||
const picked = await readPickedImages(input, room);
|
||||
if (!picked.length) return;
|
||||
gradeState.files.push(...picked);
|
||||
renderGradeReview();
|
||||
|
|
@ -348,10 +361,17 @@ $('#btn-grade').addEventListener('click', () => {
|
|||
});
|
||||
$('#grade-file').addEventListener('change', (e) => addPickedFrom(e.target));
|
||||
|
||||
// Camera shots add onto whatever's already picked (front, then flip to the
|
||||
// back for a second shot) rather than resetting — resetGradeState() is only
|
||||
// for starting a fresh card, which the library button already does.
|
||||
$('#btn-camera').addEventListener('click', () => $('#grade-camera').click());
|
||||
// Camera shots add onto whatever's already PICKED (front, then flip to the
|
||||
// back for a second shot) rather than resetting. But once a result is on
|
||||
// screen that card is finished, and adding to it is meaningless: the result
|
||||
// view has no photo strip, so renderGradeReview would keep showing the old
|
||||
// verdict while the new photos piled up invisibly behind it — silently, and
|
||||
// all the way to the 6-photo cap. Starting a new card is the only sensible
|
||||
// reading of "take a photo" at that point.
|
||||
$('#btn-camera').addEventListener('click', () => {
|
||||
if (gradeState.result) resetGradeState();
|
||||
$('#grade-camera').click();
|
||||
});
|
||||
$('#grade-camera').addEventListener('change', (e) => addPickedFrom(e.target));
|
||||
$('#grade-review').addEventListener('click', (e) => {
|
||||
if (e.target.closest('#grade-add-more')) { $('#grade-file').click(); return; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue