Pinitsdv opened a new pull request, #8628:
URL: https://github.com/apache/texera/pull/8628

   ### What changes were proposed in this PR?
   
   The palette search compares the query against `userFriendlyName` only. A 
query
   phrased as an intent — "remove repeated rows" — matches no name, so it 
returns
   nothing, even though `Distinct`'s own description says exactly that. Every
   operator carries an `operatorDescription`; the search never read it.
   
   This PR ranks operators **by meaning as well as by name, in the same box**,
   with no mode to choose:
   
   - **Keyword results render immediately and keep their places.** Typing a name
     behaves exactly as today and never waits on a model.
   - **Ranked results fill in beneath** when the model answers. A phrase matches
     no name, so it is served by the ranker alone.
   - **If the model fails to load, the keyword results stand on their own** — 
the
     current behaviour.
   - Each result shows its description, and ranked ones their similarity score.
   
   How it works:
   
   - `frontend/scripts/generate-operator-embeddings.mjs` embeds each operator's
     name, group, description and optional hand-written phrasings
     (`frontend/scripts/operator-hints.json`) **offline**, and the vectors are
     committed as `frontend/src/assets/operator-embeddings.json` (~490 KB).
   - At runtime only the query is embedded, in the browser, with
     `Xenova/all-MiniLM-L6-v2` through Transformers.js, then compared by cosine
     similarity against the committed vectors. No backend, no API key.
   - Queries carry a sequence number so a slow answer to an earlier keystroke
     cannot overwrite a newer one.
   
   **Measured.** 166 queries, one per operator, written by a team member from 
the
   operator catalogue without seeing the index or the phrasings; expected 
answers
   fixed before running.
   
   | | top-1 | top-3 |
   |---|---|---|
   | Current search (keyword only) | 1 / 166 | 2 / 166 |
   | Ranker alone | 101 / 166 | 137 / 166 |
   | **This PR (keyword first, ranked beneath)** | **99 / 166** | **137 / 166** 
|
   
   Measured over the operators the palette actually offers (it leaves out
   `PythonUDF` and `Dummy`), with Texera's own fuse.js options. Putting keyword
   matches first costs two top-1 hits — a similarly named but wrong operator
   occasionally leads — and nothing in the top three; in exchange, typing a name
   stays exact and instant. Queries that name the operator still rank it first
   (10 / 10). Of the misses, several are catalogue duplicates no ranker can 
separate
   (`KNN Classifier` / `K-nearest Neighbors`, `Radar Chart` / `Radar Plot`); 
they
   are counted as misses. We benchmarked five models; `all-MiniLM-L6-v2` was 
both
   the smallest and the most accurate on operator text, which is a dozen words
   rather than a paragraph.
   
   ### Notes for reviewers — please weigh in on these
   
   1. **Runtime downloads.** On the first search in a browser, Transformers.js
      fetches the model (~23 MB) from `huggingface.co` and the ONNX Runtime WASM
      files from `cdn.jsdelivr.net`, then caches them. That will not work in an
      air-gapped deployment, and a strict CSP would need both hosts allowed. The
      search degrades to keyword-only when they are unreachable, so nothing 
breaks,
      but if you would rather self-host both under `assets/` we can do that 
here or
      as a follow-up.
   2. **Dependency footprint.** `@xenova/[email protected]` adds five 
packages to
      the bundle (declared in `LICENSE-binary`; all MIT or Apache-2.0, none 
ships a
      NOTICE). Its dev tree also pulls `onnxruntime-node` and `sharp`, which are
      Node-only and are not bundled. The library is imported lazily, so it stays
      out of the initial bundle.
   3. **Keeping the index current.** The committed vectors only need 
regenerating
      when an operator is added or its name, group or description changes. The
      script runs against the output of `GET /api/resources/operator-metadata`. 
We
      are happy to wire it into CI if you prefer that to a manual step.
   
   ### Any related issues, documentation, discussions?
   
   Part of #8627
   
   ### How was this PR tested?
   
   - Added five cases to `operator-menu.component.spec.ts` with a stubbed 
ranker,
     so no model is downloaded in tests: keyword matches appear before the 
ranker
     answers; they keep their places with ranked ones filled in beneath, once 
each;
     a phrase that names nothing is served by the ranker; a slow answer to an
     earlier keystroke is dropped; the keyword matches stand when the ranker 
fails.
     The 12 existing cases still pass (17 in total).
   - `yarn build:ci` succeeds, and `bin/licensing/check_binary_deps.py
     --ignore-transitive-version npm frontend/dist/3rdpartylicenses.json` 
reports
     all bundled packages matched.
   - The 166-query evaluation above, re-run against the merged behaviour this 
PR ships.
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Claude Opus 5)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to