(candidates, prompt_chars)
| 747 | options = [ |
| 748 | candidate |
| 749 | for candidate in candidates |
| 750 | if id(candidate) not in used_ids and candidate.get('char') == prompt_char |
| 751 | ] |
| 752 | if not options: |
| 753 | resolved.append(None) |
| 754 | continue |
| 755 | chosen = sorted(options, key=lambda item: (float(item.get('score') or 0), int(item.get('area') or 0)), reverse=True)[0] |
| 756 | used_ids.add(id(chosen)) |
| 757 | resolved.append(chosen) |
| 758 | |
| 759 | missing_indexes = [index for index, item in enumerate(resolved) if item is None] |
| 760 | unknown_candidates = [ |
| 761 | candidate |
| 762 | for candidate in candidates |
| 763 | if id(candidate) not in used_ids and not candidate.get('char') |
| 764 | ] |
| 765 | if len(missing_indexes) == 1 and len(unknown_candidates) == 1: |
| 766 | missing_char = prompt_chars[missing_indexes[0]] |
| 767 | candidate = dict(unknown_candidates[0]) |
| 768 | candidate['char'] = missing_char |
| 769 | candidate['text'] = missing_char |
| 770 | candidate['score'] = max(min(float(candidate.get('score') or 0) * 0.9, 0.85), 0.55) |
| 771 | candidate['source'] = 'yellow_component_prompt_fill' |
| 772 | resolved[missing_indexes[0]] = candidate |
| 773 | |
| 774 | if any(item is None for item in resolved): |
| 775 | return candidates |
| 776 | |
| 777 | return [dict(item) for item in resolved] |
| 778 | |
| 779 | |
| 780 | def build_yellow_fallback_candidates(image, prompt_chars, engine): |
| 781 | boxes = build_yellow_component_boxes(image, len(prompt_chars)) |
| 782 | if len(boxes) != len(prompt_chars): |
| 783 | return [] |
| 784 | candidates = recognize_yellow_boxes(image, boxes, prompt_chars, engine) |
| 785 | if len(candidates) != len(prompt_chars): |
| 786 | return [] |
| 787 | if not all(candidate.get('char') in prompt_chars for candidate in candidates): |
no outgoing calls
no test coverage detected