← back to Dw Pairs Well
tools/pattern-texture-vision-stub.py
55 lines
#!/usr/bin/env python3
"""DESIGN-ONLY STUB — texture-aware local-vision confirm for pattern grouping.
DTD exception #3: the color-invariant dHash FALSE-SPLITS organic textures
(grasscloth/linen/raffia/cork — fibers are random; Aloha Grass → 7 false
clusters). For texture multi-colorway groups that DON'T have a trusted mfr_sku
root (or that are suspiciously huge), we confirm with a FREE local Ollama
vision pass (qwen2.5vl on Mac1/Mac2) instead of the dHash gate.
THIS IS A STUB. It is NOT wired to run a 74k job. It documents the intended
call shape so the gated apply step can implement it. Cost = $0 (local Ollama).
Intended flow (per candidate group, post mfr_root/T2 keying):
1. Pull the group's member image_urls (read-only, from the mirror).
2. For each pair (or representative-vs-member), ask qwen2.5vl ONE question:
"Are these two images the SAME woven/textured pattern in different
colorways, ignoring color? Answer YES or NO."
-> tolerant of random-fiber noise that breaks dHash; sensitive to a real
motif/weave-structure change (so a generic-title over-merge still splits).
3. Members the model says match the representative stay in the cluster;
non-matches split into their own pattern_id (suffix ::v2, ::v3 …).
Hard gotchas (from MEMORY):
- Normalize each image Pillow -> JPEG before sending to Ollama; it rejects
CMYK/WebP (word-salad otherwise).
- Use OLLAMA_KV_CACHE_TYPE=f16 for vision (q4_0 KV cache breaks vision).
- Mac1 text inference can wedge while vision still serves; prove health via
/api/generate num_predict:1 before a batch, fail over to Mac2 127.0.0.1.
- This is the SAME local-hybrid pattern as enrich-ai-tags (qwen2.5vl), $0.
Reference (do not duplicate): tools/pattern-image-verify.py is the dHash gate
for the NON-texture bucket; this stub is its texture-safe sibling.
"""
import os, sys
OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://127.0.0.1:11434")
VISION_MODEL = os.environ.get("VISION_MODEL", "qwen2.5vl")
PROMPT = ("Are these two wallcovering images the SAME woven/textured pattern in "
"different colorways, ignoring color and minor fiber noise? "
"Answer with a single word: YES or NO.")
def confirm_texture_group(member_urls):
"""STUB — returns clusters. Not implemented; raises so nobody runs it blind."""
raise NotImplementedError(
"Design-only stub. Implement during the GATED apply step: normalize each "
"image to JPEG (Pillow), POST to %s /api/chat with model=%s and PROMPT, "
"parse YES/NO, cluster. $0 local. See module docstring." % (OLLAMA_URL, VISION_MODEL))
if __name__ == "__main__":
print(__doc__)
print(f"\n[stub] OLLAMA_URL={OLLAMA_URL} VISION_MODEL={VISION_MODEL} cost=$0 (local)")
print("[stub] Not runnable — design reference only. Exiting 0.")
sys.exit(0)