Spaces:
Running
Running
Commit History
3 days ago
-
Fix semantic search: space-query product filtering, neon on top CLIP results, tighter layout, always show matched avatar interiors
- merge.js: pure-semantic queries (phòng khách, nhà phố, biệt thự...) never crowd-out interiors; space queries filter products whose name lacks a query-specific token (sofa phòng khách keeps sofa, khóa cửa phòng ngủ is dropped); matched avatar interiors always enter the field, not only on empty query - relevance.js: space queries ring the top CLIP cosine band (relative 0.85x top, floor 0.20) even without a verbatim caption match - layout.js: results spiral tighter (0.62/0.66) with reduced pill clearance so results sit near the search box - semantic-terms.js: SPACE_QUERY_TERMS + isSpaceQuery for nhà phố/biệt thự/phòng ngủ/nhà cấp 4/căn hộ... - index.html: bump cache-bust version to 20261110-17ce3b43
4 days ago
-
Semantic search fix for VSEARCH (semantic-image-field):
Verified signature1. src/merge.js: crowd-out now uses productLikeTerms() from semantic-terms.js (previously written but never imported) — "kệ xoong"/"máy hút mùi"/"bếp từ" crowd out interiors; "nhà phố"/"biệt thự"/"nội thất"/"bàn ghế" keep them. Products never ring (neon) on semantic queries — only the actual photo the user asked for gets the neon ring, not kitchen accessories. 2. src/avatar-interiors.js: add missing import { expandQueryTerms } — otherwise every avatar-interior text match threw ReferenceError (broken semantic caption matching: "nhà phố" -> "nhà ống", "biệt thự" -> "villa"). 3. src/semantic-terms.js: expand SEMANTIC_SYNONYMS (nha/ong/lien, biet/thu/villa/vuon, phong/khach/ngu/tam, ban/ghe) for better recall. 4. scripts/refresh.mjs: helper script to rebuild bundle and push. Run: node scripts/refresh.mjs (needs HF_TOKEN) to rebuild the static bundle.d5530f7 -
Upload scripts/refresh.mjs
Verified signature377e476
5 days ago
-
test: acceptance suite for semantic vs product search behaviour
Verified signatured29ef61 -
refresh script fixes: STABLE_STYLE=app.css (build thực tế), strip query string khi verify index.html refs
17a669e -
refresh script: git-lfs guard cho og-image.png (pre-receive hook rejects raw binaries)
a2a3b1c -
SEO + social-share thumbnail: ảnh ghép 12 ảnh mới nhất tự động
- README YAML thumbnail: dist/share/og-image.png → hub og:image = ảnh ghép - .gitattributes: og-image.png qua LFS (HF pre-receive hook yêu cầu) - scripts/gen-thumbnail.py: fetch 8 nội thất mới nhất + 4 SP mới nhất, compose grid 4x3 1200x675 PNG vào public/ + dist/share/ - refresh-catalogue.mjs: chạy gen-thumbnail trước build, commit public/share+dist/share - index.html root: đầy đủ og:title/description/url/image + twitter card + canonical + robots + keywords (SEO cho link chia sẻ lẫn Google)c913ae2
7 days ago
-
fix: restore Eurogold images + kệ xoong search precision
- catalogue.js: SKU upsert prefers the row whose lead image is live, so a dead V.AISTUDIO /eurogold_img/ row can no longer clobber a live www.eurogold.vn photo (221 dead Eurogold leads -> 5). - catalogue.js: recoverDeadLeads maps dead-only SKUs through the dead filename itself (EPD4635VX->EPD4635.jpg, EUM101->EUM101L.jpg ...), restoring 16 more products deterministically. - product-search.js: kệ/giá name synonyms so 'kệ xoong' finds Eurogold 'Giá xoong nồi' racks; per-score-group round-robin tie-break so one brand family cannot swallow the field (Eurogold now visible in top-24). - merge.js: a strong product query (every term in a product name) drops CLIP interiors from the field -- kệ xoong shows ONLY racks; keywordFeatured defaults to productLimit so every relevant hit gets the neon ring+scale; leadImage refuses dead V.AISTUDIO dirs; PRODUCT_LIMIT 12->24. - App.jsx/worker.js: search-products limit 24->48. - tests: updated caps test (24), worker-shape score, added cro…aba5d22
9 days ago
-
test: pin the share-URL routing rule so avatarimg can never return to /share/p/
Verified signatureefd2db0 -
test(neon): assert the sweep angle advances and the ring layer stays untransformed
Verified signature9065e5e -
Restore viewer CSS, ring only the newest ten, and clear the search pill
ML Intern1. CSS. The previous commit stripped the size/position controls with a script that cut from .field-controls to the end of the file, taking 147 lines with it: every .photo-* rule, .search-status, .search-progress and .footer. It went unnoticed because an unstyled <dialog> still opens, still shows the photograph, and never throws -- it just renders a raw UA box with the share toolbar stacked as plain text. Restored verbatim from the last good revision; app.css goes 17.1kB -> 24.7kB. 2. Ten rings, not sixty. RECENT_LIMIT (shown) and FEATURED_LIMIT (ringed) are now separate constants, because "show more photographs" and "only the newest glow" pull in opposite directions if one list drives both. 24 rings on a dense field is decoration rather than emphasis. The rest still render -- as ordinary tiles, which is what the brief asks for and what makes the ten legible. 3. More photographs: fieldCount 96/56 -> 150/96. Raised less on phones because tile area is bo…f134575 -
Ring every exact hit with running neon, and sync vai-avatar's newest photos
ML InternFour changes, all of them visible at a glance: 1. The neon outline now RUNS. It was a static ring with a breathing glow; it is a conic gradient masked to a 2px border and rotated every frame, so the light travels around the edge. An animated border-color cannot do this (borders take no gradient) and an animated box-shadow only pulses in place. The stroke is on ::before and the halo on ::after, because one pseudo-element can hold only one background and the ring needs both. mask-composite turns the full-size gradient into an outline; without it the gradient would fill the tile and hide the photograph, so the test asserts the mask is present. 2. Interiors published on vai-avatar now appear here. src/avatar-interiors.js reads bep40/vai-avatar2-interior/index.json, which is the file carrying created_at -- 153 rows, newest 2026-10-05. metadata.json has 1,752 rows but no timestamps at all, so it cannot answer "newest". These are matched by TEXT, not by th…eb92bc7 -
Ignore pre-existing dataset CORS noise in the UI check
ML InternRunning the browser check against the live Space surfaced 173 CORS errors on interior-photograph requests from the dataset CDN. Those are not caused by the backdrop/search/controls/neon work -- DATASET in src/assets.js is untouched by it -- and they come from the headless host's own network policy, not from the app. They were drowning out any real regression, so the filter now names CORS explicitly and says why. The field paints without them: the tile layer falls back to the BlurHash placeholder.9feb79c -
V.AI STUDIO backdrop, vai-avatar's product search, size/position, neon
ML InternFour changes, all on the search field. Background. The same artwork vai-avatar shows on its body (public/avatars/vaistudio_center.png, copied byte-for-byte, md5 checked) at 30% opacity. It is a separate fixed layer rather than a background-image on .app because opacity on .app would fade the photographs and the search pill with it, and background-attachment:fixed cannot compose with the .vignette and .grain layers already sitting on top of the field. Product search. Ranking is now vai-avatar's own scoreProduct(), ported to product-search.js rather than extended in place, so the two modules can be diffed against each other when the original changes. The whole rule set carries over: exact SKU/model/title must win outright, millimetre sizes are compared numerically (the specs write "900 mm", "900mm" and "W900" for the same shelf), material words are matched against specs as well as title, and brand names get a flat bonus. 35 tests in scripts/test-product-search.mjs pin each rule. Both s…0df020e
11 days ago
-
feat(sync): two-way interior sync against vai-avatar's library
Verified signatureThe field is missing 51 interiors vai-avatar serves, and still holds 151 the user deleted there. Copying files cannot close the gap. The field searches with its own CLIP matrix; vai-avatar's library uses a different model, so a new image has to be encoded with the field's model or it lands in a 512-dim space the field never searches. Measured: cosine between the two datasets on the 377 images they share is 0.6347, and cosine between two different images is 0.6336. Same size, no signal. The script reads the API's live list rather than metadata.json, which retains deleted rows (1,752 rows for 1,122 live images) and would resurrect anything the user removed. Verified against the real files: the headerless float32 codec round-trips the 2.4 MB blob byte-identically, the index and blob agree at 1,222 rows, new records carry exactly the scraper's fields, and a dry run reports +51 / -151. Run: pip install -r scripts/requirements-sync.txt python scripts/sync-interiors.py --dry-run07cd7be
12 days ago
-
feat: product share links + repair Malloca/Hafele misbranding
Verified signatureTwo things. Share links. vai-avatar served share pages for interior images and chat answers but nothing for products, so a product link had nowhere to point. A /share/p/<sku> route now exists there and resolves against VAIX_PRODUCTS, the 11,704-row catalogue that Space already loads. A "Xem thêm" button in the viewer toolbar links products to it and interiors to the existing /share/i/. The link is keyed on the photo, not the image, so paging a gallery still shares the product rather than one of its photographs. Misbranding. 99 rows are named "Malloca | ..." while their brand field says Hafele, and all 1,011 of their image URLs point at Hafele's CDN rather than the Malloca storefront. Hafele resells Malloca, so these are Malloca products catalogued under the wrong brand. 77 now show a real Malloca photograph and the remaining 22, which have no Malloca row anywhere in the file, keep their photo with the brand corrected. No product is dropped and no non-Malloca row is touched. Matching…9bf56b3 -
fix(catalogue): stop dropping 355 Malloca products that are not duplicates
Verified signature3fa0a11 -
feat(catalogue): load the full 8,162-product shop, not just pasted URLs
Verified signaturea301301 -
feat(field): merge Malloca products into the interior image field
Verified signaturee34a847 -
feat(catalogue): seed mirror without a Vite build
Verified signature2a7159f
13 days ago
-
Upload scripts/sync-catalogue.mjs
Verified signature0aa45f0 -
fix(sync): fail loudly on a PARTIAL mirror, and match entrypoint by realpath
Verified signatureTwo defects in the mirror sync, both of which produce "sửa sp không đồng bộ" with no error anywhere. 1) A partial fetch failure exited 0. The good file was written, the bad one was not — but public/catalogue is already committed, so the failed file stayed on disk as its previous version. refresh-catalogue.mjs then passed its requireRealFile + recordCount guards on that stale data, built, committed and printed REFRESH_OK. Result: products.json fresh, promos.json stale, so upstream edits and deletes silently stopped applying. That contradicts this file's own failure policy (and refresh-catalogue.mjs's): the previously committed mirror keeps serving. It did not — the push replaced it with a mixed one. Now ANY source failure fails the run, so the caller aborts before build/push and the last-good mirror stays live. The good file is still written, so one transient error does not discard a successful fetch; it just may not be published. 2) The direct-run c…1a32c2e -
Upload scripts/refresh-catalogue.mjs
Verified signature5a68e72 -
Upload scripts/refresh-catalogue.mjs
Verified signature280908b -
Upload scripts/refresh-catalogue.mjs
Verified signaturefb17130 -
Upload scripts/refresh-catalogue.mjs
Verified signature21d5365 -
Upload scripts/refresh-catalogue.mjs
Verified signature3460919 -
Upload scripts/refresh-catalogue.mjs
Verified signature6c22abf -
Upload scripts/refresh-catalogue.mjs
Verified signaturec573dc7 -
Upload scripts/refresh-catalogue.mjs
Verified signature5b9f2f1 -
fix: restore refresh-catalogue.mjs, truncated by a partial upload
Verified signatureThe previous commit replaced this file with only its middle section: the shebang, imports, main(), clone/install/sync steps and the mirror validation were all dropped, leaving `ok('built')` at top level and a ReferenceError on the first line. This restores the complete script with the intended changes — asset-reference verification moved ahead of the commit, and a guard that fails loudly if the build deletes the committed dist/ data.744798f -
fix: verify the served page before pushing, not after
Verified signatureThe asset-reference check ran after `git push`. index.html is not a Vite build input, so a stale reference is exactly the state that blanks the Space — and it was being published first, then reported. Move the check ahead of the commit so a bad build aborts with the last good bundle still serving. Also assert dist/prodimgs, products-gallery.json and products-index.json survive the build. src/ reads nothing from them, so their disappearance would not break the app or raise any error; this turns a silent 87 MB data loss into a loud failure.3279632 -
Upload scripts/refresh-catalogue.mjs
Verified signatureb19467c -
Add scheduled catalogue refresh script: clone, sync, build, commit, verify index.html refs
Verified signature720759a -
Upload scripts/sync-catalogue.mjs
Verified signaturec86d53a