MissawB commited on
Commit
68ebffc
·
verified ·
1 Parent(s): 91f3fd5

Upload folder using huggingface_hub (part 2)

Browse files
Files changed (2) hide show
  1. backend/pipeline/vector_client.py +38 -25
  2. docs/HISTORY.md +13 -0
backend/pipeline/vector_client.py CHANGED
@@ -334,32 +334,45 @@ class PGVectorCollectionWrapper:
334
  model_name,
335
  ],
336
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  else:
338
- # Sans `document`, cette branche calcule NULL --
339
- # elle ne lit JAMAIS `embeddings` (l'embedding
340
- # vient de `embedding(model, doc)`, pas d'un
341
- # vecteur déjà calculé). Si l'appelant A fourni un
342
- # vecteur (ex. `VisualIndexService.index`, qui
343
- # n'appelle jamais `upsert_items` avec des
344
- # `documents`), l'écrire quand même en NULL le
345
- # jetterait en silence : `strict=True` ne se
346
- # déclenche jamais (aucune exception ne remonte),
347
- # et l'appelant annonce un succès pour une ligne
348
- # sans vecteur. Dormant sur Neon/Cloud SQL
349
- # aujourd'hui ; armé le jour où quelqu'un pointe
350
- # ceci sur une vraie instance AlloyDB.
351
- if embeddings is not None and embeddings[i]:
352
- raise ValueError(
353
- f"AlloyDB AI branch: item {item_id!r} in "
354
- f"collection {self.name!r} was given a "
355
- "computed embedding but no `document` -- "
356
- "this branch derives the embedding FROM "
357
- "`documents` (`embedding(model, doc)`) and "
358
- "silently writes NULL otherwise, discarding "
359
- "the vector the caller already computed. "
360
- "Refusing rather than writing a vectorless "
361
- "row that looks like a successful upsert."
362
- )
363
  sql = """
364
  INSERT INTO animetix_vectorrecord (collection_name, item_id, embedding, metadata, document, created_at)
365
  VALUES (%s, %s, NULL, %s, NULL, NOW())
 
334
  model_name,
335
  ],
336
  )
337
+ elif embeddings is not None and embeddings[i]:
338
+ # No `document`, but the caller supplied a
339
+ # precomputed vector (exactly `VisualIndexService.
340
+ # index`'s shape: it hands over vectors it computed
341
+ # itself, never raw text). The `embedding(model,
342
+ # doc)` derivation does not apply here -- but
343
+ # writing NULL would silently discard the caller's
344
+ # vector. Persist the supplied vector directly, as a
345
+ # pgvector literal. Dormant on Neon/Cloud SQL today
346
+ # (is_alloydb_ai_supported() is False there); this is
347
+ # what makes the visual index buildable the day
348
+ # someone points this at a real AlloyDB instance.
349
+ vec_literal = (
350
+ "["
351
+ + ",".join(str(float(x)) for x in embeddings[i])
352
+ + "]"
353
+ )
354
+ sql = """
355
+ INSERT INTO animetix_vectorrecord (collection_name, item_id, embedding, metadata, document, created_at)
356
+ VALUES (%s, %s, %s::vector, %s, NULL, NOW())
357
+ ON CONFLICT (collection_name, item_id)
358
+ DO UPDATE SET
359
+ embedding = EXCLUDED.embedding,
360
+ metadata = EXCLUDED.metadata,
361
+ document = EXCLUDED.document;
362
+ """
363
+ cursor.execute(
364
+ sql,
365
+ [
366
+ self.name,
367
+ str(item_id),
368
+ vec_literal,
369
+ json.dumps(clean_metas[i]),
370
+ ],
371
+ )
372
  else:
373
+ # No document AND no vector: a metadata-only row
374
+ # (embedding NULL) is the honest answer -- nothing
375
+ # is being discarded.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  sql = """
377
  INSERT INTO animetix_vectorrecord (collection_name, item_id, embedding, metadata, document, created_at)
378
  VALUES (%s, %s, NULL, %s, NULL, NOW())
docs/HISTORY.md CHANGED
@@ -2,6 +2,19 @@
2
 
3
  This document archives the major milestones of the project's technical evolution.
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  ## [2026-07-15] Session: Technical-debt sweep — hardcoded config & data externalized, duplicated logic unified
6
 
7
  Closure of five 🟡 items from the *audit dette 2026-07-11*.
 
2
 
3
  This document archives the major milestones of the project's technical evolution.
4
 
5
+ ## [2026-07-16] Session: Dockerfile hardening, Covertest→Postgres, coverage & fetch hygiene, script archive, BlindtestPage split, CCIP integration guard
6
+
7
+ - **Dockerfile hardening (safe subset).** `Dockerfile.brain` runtime → `python:3.12-slim` (bake stages left on 3.11 to preserve the ~90-min merge cache); `Dockerfile.dataflow` drops root to a non-root `appuser` after apt/pip. Brain stays root by design (Ollama installs as root, the GPU path is untestable and CI never rebuilds the brain); the dataflow non-root drop is **unverified against a real Dataflow submission** — revert the `USER` block if the runner rejects it. The `:latest` launcher is kept (Google's recommended form, with pin-by-digest instructions in-file).
8
+ - **Covertest — covers out of the JSON blob.** `manga_covers.json` (0.5 → ~25 MB, loaded entirely into RAM by the pgvector singleton at first call) moved to a Postgres `MangaCover` model with on-demand lookups (`sync_covers` command + migration).
9
+ - **`finetuning_dataset` coverage 65 → 85%.** Hermetic integration tests over the language×tier matrix (anime/manga/character), language omission, Alpaca-base load exceptions, out-of-bounds noise, and multi-turn noise.
10
+ - **Raw-`fetch()` toast hygiene.** Failure toasts harmonized on `MangaVoicePage`, `offlineLibrary` (via a `useChapterDownload` hook), and the OpenData download (`OpenDataPage` / `labService`); the three keep raw `fetch` on purpose (binary / cross-origin) but now surface an `error` toast.
11
+ - **Frontend coverage gate raised** to match reality and block regressions: 29→38 statements / 22→28 branches / 28→34 functions / 29→39 lines.
12
+ - **`scripts/` cleaned.** 7 unused one-offs → `scripts/archive/`, stale `test_*.pyc` purged, and a `scripts/README.md` documenting the active and archived scripts.
13
+ - **`BlindtestPage.tsx` 753 → 324 lines**, extracting a `useBlindtestGame` hook plus `BlindtestPlayer` / `BlindtestSecretReveal` / `BlindtestBonusRecap` components. The other >500-line components (TransparencyPage, AudioLabPage, LabHubPage, SpeechToSpeechLabPage) remain and stay tracked as open.
14
+ - **CCIP integration guard.** A new `integration`-marked test (`tests/adapters/test_ccip_vision_integration.py`) drives the real `deepghs/ccip_onnx` graph over real catalog portraits and pins the end-to-end property — 768-d, non-zero, deterministic, discriminating (mean cross-character ~0.33 ≪ self ~1.0), size-invariant, query-ranks-self — that a subtly-wrong preprocessing change would break while passing the mocked units. De-risks the phase-2 character build (which remains a prod job).
15
+ - **AlloyDB upsert persists a supplied vector.** `PGVectorCollectionWrapper.upsert`'s AlloyDB-AI branch derives embeddings from `documents` via `embedding(model, doc)`; handed a precomputed vector with no document — exactly `VisualIndexService.index`'s shape — it used to *raise* (a guard against silently writing NULL). It now persists the supplied vector directly as a pgvector literal (`%s::vector`), so the visual index is buildable the day this points at a real AlloyDB instance. The genuine no-vector/no-document case still writes NULL. Dormant on Neon/Cloud SQL (`is_alloydb_ai_supported()` is False there).
16
+ - **`reconcile_db` no longer issues a clean bill of health for a store it skipped.** When Neo4j was offline (the dead local URI → `driver is None`) the command skipped every graph check but still printed "[SUCCESS] All sampled items are synchronized across Django, pgvector, **and Neo4j**" — the skip went unnoticed behind a green verdict. The verdict now lists the stores actually checked and, when any was skipped, warns their synchronization is `UNVERIFIED` rather than confirmed; full SUCCESS only when every store was reached. The dead local URI itself remains an operator config action (point `NEO4J_URI` at a live instance).
17
+
18
  ## [2026-07-15] Session: Technical-debt sweep — hardcoded config & data externalized, duplicated logic unified
19
 
20
  Closure of five 🟡 items from the *audit dette 2026-07-11*.