Conversation
Add the React + EUI web component, directive examples, and integration docs under tools/vector_sizing_calculator to stage migration into docs-builder. Co-authored-by: Cursor <cursoragent@cursor.com>
Move the vector sizing calculator React/EUI implementation into Elastic.Documentation.Site web-components and register it from the main asset entrypoint. Co-authored-by: Cursor <cursoragent@cursor.com>
|
💚 CLA has been signed |
| ).join(''); | ||
|
|
||
| // Disk bar chart | ||
| const maxDisk = Math.max(...diskItems.map(i => i.value), 1); |
reakaleek
left a comment
There was a problem hiding this comment.
What files are in tools folder? Are they still needed?
Also the *.cs files should probably be in https://github.com/elastic/docs-builder/tree/main/src/Elastic.Markdown/Myst/Directives
…rkdown Move directive implementation from tools/ staging into Myst/Directives/VectorSizing. - Register block in DirectiveBlockParser and render via Razor slice in DirectiveHtmlRenderer - Add VectorSizingBlockTests - Update tools/vector_sizing_calculator docs to point at in-repo source of truth; remove duplicate C# snippets from docs-builder-directive/ Made-with: Cursor
Add syntax doc with live directive block and TOC entry so docs-builder serve exposes a stable URL for design review (e.g. /syntax/vector-sizing-calculator). Link from directives index. Made-with: Cursor
📝 WalkthroughWalkthroughThis pull request introduces a vector sizing calculator feature that estimates disk and off-heap memory requirements for Elasticsearch ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/calculations.ts`:
- Around line 66-113: The validate function currently omits checks for replicas,
hnswM, and vectorsPerCluster which leads to invalid math downstream; update
validate(inputs: CalculatorInputs) to also validate replicas (ensure replicas >=
0), hnswM (when indexType === 'hnsw' ensure hnswM >= 2), and vectorsPerCluster
(when indexType === 'disk_bbq' ensure vectorsPerCluster >= 1), and return {
valid: false } with a clear warning message (and optional warningLink) for each
violated constraint so calculate() never receives zero/negative/undefined
values; apply the same additions to the mirrored
tools/vector_sizing_calculator/web-component/src/calculations.ts validate
implementation.
In `@tools/vector_sizing_calculator/embed.html`:
- Around line 428-439: The early-return paths do not clear the same UI state as
the initial validation block, so stale results remain when D>4096 (and other
invalid inputs) trigger a return; update the D>4096 branch (and any other
early-return branch) to call the same UI-reset steps used when
isNaN(V)||isNaN(D)||V<=0||D<=0 — i.e., reset $('vscTotalDisk'),
$('vscTotalRam'), $('vscTotalDiskB'), $('vscTotalRamB'), $('vscDiskBD'),
$('vscRamBD'), $('vscDiskChart'), $('vscRamChart'), clear
$('vscFormulas').textContent and hide $('vscCluster') before showing the warning
via w.classList.add('vsc-visible') and setting wm.innerHTML; ensure the reset is
applied consistently wherever the function returns early.
In `@tools/vector_sizing_calculator/index.html`:
- Around line 394-398: The standalone preview must mirror the React calculators:
block selecting "disk_bbq" in the indexType select unless quantization is
"float" or "bfloat16", so update the indexType handling (select id="indexType")
and the preview recalculation path (e.g., the function that computes
byte/bit/preview results) to disable or remove the "disk_bbq" option when
quantization is not float/bfloat16 and re-select a valid index if needed;
additionally validate the bbqVpc input (bbqVpc) to require > 0 and short-circuit
the calculation (return an error/skip and avoid computing Infinity) when
invalid, and ensure any quantization change handler also re-sync indexType state
so the inline preview cannot compute bit/byte + disk_bbq combinations that the
shipped React calculators disallow.
In `@tools/vector_sizing_calculator/sizing-section.md`:
- Around line 326-335: The table's quantized column values and reduction factors
are inconsistent with the note that says "Bytes per vector include HNSW graph
overhead (+64 bytes)"; fix by choosing one canonical definition and applying it
consistently: either (A) add the 64-byte HNSW overhead to every quantized value
(e.g., change 384-dim int8 from 388 B/vec to 452 B/vec) and recompute the
reduction factors vs the unquantized baseline, or (B) change the note to state
that the table shows quantized vector bytes only (exclude the 64 B graph
overhead) and update the reduction factors to compare vector-only sizes; update
the rows for Dimensions (384, 768, 1024, 1536) and the reduction factor
parentheses accordingly so all values and the note use the same basis.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fb1c8011-775f-4a4c-9883-392f1675ceb5
⛔ Files ignored due to path filters (2)
tools/vector_sizing_calculator/web-component/dist/vector-sizing-calculator.iife.jsis excluded by!**/dist/**tools/vector_sizing_calculator/web-component/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (40)
docs/_docset.ymldocs/syntax/directives.mddocs/syntax/vector-sizing-calculator.mdsrc/Elastic.Documentation.Site/Assets/main.tssrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/Calculator.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/VectorSizingCalculatorComponent.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/calculations.tssrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/components/BreakdownChart.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/components/ClusterTotals.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/components/ConfigurationPanel.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/components/FormulasPanel.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/components/ResultsPanel.tsxsrc/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/types.tssrc/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cssrc/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cssrc/Elastic.Markdown/Myst/Directives/VectorSizing/VectorSizingBlock.cssrc/Elastic.Markdown/Myst/Directives/VectorSizing/VectorSizingView.cshtmlsrc/Elastic.Markdown/Myst/Directives/VectorSizing/VectorSizingViewModel.cstests/Elastic.Markdown.Tests/Directives/VectorSizingBlockTests.cstools/vector_sizing_calculator/INTEGRATION.mdtools/vector_sizing_calculator/docs-builder-directive/DirectiveBlockParser.patch.mdtools/vector_sizing_calculator/docs-builder-directive/usage-in-docs-content.mdtools/vector_sizing_calculator/embed.htmltools/vector_sizing_calculator/index.htmltools/vector_sizing_calculator/sizing-section.mdtools/vector_sizing_calculator/web-component/index.htmltools/vector_sizing_calculator/web-component/package.jsontools/vector_sizing_calculator/web-component/src/Calculator.tsxtools/vector_sizing_calculator/web-component/src/calculations.tstools/vector_sizing_calculator/web-component/src/components/BreakdownChart.tsxtools/vector_sizing_calculator/web-component/src/components/ClusterTotals.tsxtools/vector_sizing_calculator/web-component/src/components/ConfigurationPanel.tsxtools/vector_sizing_calculator/web-component/src/components/FormulasPanel.tsxtools/vector_sizing_calculator/web-component/src/components/ResultsPanel.tsxtools/vector_sizing_calculator/web-component/src/eui-icons.d.tstools/vector_sizing_calculator/web-component/src/icon-cache.tstools/vector_sizing_calculator/web-component/src/main.tsxtools/vector_sizing_calculator/web-component/src/types.tstools/vector_sizing_calculator/web-component/tsconfig.jsontools/vector_sizing_calculator/web-component/vite.config.ts
| export function validate(inputs: CalculatorInputs): ValidationResult { | ||
| const { numVectors, numDimensions, elementType, quantization, indexType } = | ||
| inputs; | ||
|
|
||
| if ( | ||
| isNaN(numVectors) || | ||
| isNaN(numDimensions) || | ||
| numVectors <= 0 || | ||
| numDimensions <= 0 | ||
| ) { | ||
| return { valid: false }; | ||
| } | ||
|
|
||
| if (numDimensions > 4096) { | ||
| return { | ||
| valid: false, | ||
| warning: | ||
| 'Elasticsearch supports a maximum of 4,096 dimensions for dense_vector fields.', | ||
| warningLink: | ||
| 'https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-params', | ||
| }; | ||
| } | ||
|
|
||
| if ( | ||
| (elementType === 'byte' || elementType === 'bit') && | ||
| quantization !== 'none' && | ||
| indexType !== 'disk_bbq' | ||
| ) { | ||
| return { | ||
| valid: true, | ||
| warning: `Quantization is not applicable to ${elementType} element type.`, | ||
| }; | ||
| } | ||
|
|
||
| if ( | ||
| elementType === 'float' && | ||
| numDimensions >= 384 && | ||
| quantization === 'none' && | ||
| indexType !== 'disk_bbq' | ||
| ) { | ||
| return { | ||
| valid: true, | ||
| note: 'For float vectors with dimensions ≥ 384, Elastic strongly recommends using a quantized index to reduce memory footprint.', | ||
| }; | ||
| } | ||
|
|
||
| return { valid: true }; | ||
| } |
There was a problem hiding this comment.
Validate every numeric input that feeds the formulas.
validate() never checks replicas, hnswM, or vectorsPerCluster, but Lines 178, 184, 256, and 293 use them directly. Clearing those fields or entering 0/negative values can therefore yield zero/negative copy counts or Infinity DiskBBQ totals. Please reject invalid values before calculate() runs, at least for replicas >= 0, hnswM >= 2 when indexType === 'hnsw', and vectorsPerCluster >= 1 when indexType === 'disk_bbq'. The mirrored tools/vector_sizing_calculator/web-component/src/calculations.ts copy needs the same fix.
Also applies to: 177-195, 255-304
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/Elastic.Documentation.Site/Assets/web-components/VectorSizingCalculator/calculations.ts`
around lines 66 - 113, The validate function currently omits checks for
replicas, hnswM, and vectorsPerCluster which leads to invalid math downstream;
update validate(inputs: CalculatorInputs) to also validate replicas (ensure
replicas >= 0), hnswM (when indexType === 'hnsw' ensure hnswM >= 2), and
vectorsPerCluster (when indexType === 'disk_bbq' ensure vectorsPerCluster >= 1),
and return { valid: false } with a clear warning message (and optional
warningLink) for each violated constraint so calculate() never receives
zero/negative/undefined values; apply the same additions to the mirrored
tools/vector_sizing_calculator/web-component/src/calculations.ts validate
implementation.
| if(isNaN(V)||isNaN(D)||V<=0||D<=0){ | ||
| $('vscTotalDisk').textContent='—';$('vscTotalRam').textContent='—'; | ||
| $('vscTotalDiskB').textContent='';$('vscTotalRamB').textContent=''; | ||
| $('vscDiskBD').innerHTML='';$('vscRamBD').innerHTML=''; | ||
| $('vscDiskChart').innerHTML='';$('vscRamChart').innerHTML=''; | ||
| $('vscCluster').style.display='none';$('vscFormulas').textContent='';return; | ||
| } | ||
| if(D>4096){ | ||
| w.classList.add('vsc-visible'); | ||
| wm.innerHTML='Elasticsearch supports a maximum of 4,096 dimensions for dense_vector fields. <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-params" target="_blank" rel="noopener">See documentation</a>.'; | ||
| return; | ||
| } |
There was a problem hiding this comment.
Clear stale UI state before early returns
When inputs become invalid (including Line 435 dimension-limit case), the function returns without consistently clearing prior computed outputs/recommendation state, so stale sizing values can remain visible for an invalid config. Please reset result panels and note visibility before returning on invalid paths.
Proposed fix
function calc(){
@@
- if(isNaN(V)||isNaN(D)||V<=0||D<=0){
+ var noteEl=$('vscNote');
+ function clearOutputs() {
+ $('vscTotalDisk').textContent='—';$('vscTotalRam').textContent='—';
+ $('vscTotalDiskB').textContent='';$('vscTotalRamB').textContent='';
+ $('vscDiskBD').innerHTML='';$('vscRamBD').innerHTML='';
+ $('vscDiskChart').innerHTML='';$('vscRamChart').innerHTML='';
+ $('vscCluster').style.display='none';$('vscFormulas').textContent='';
+ noteEl.style.display='none';
+ }
+
+ if(isNaN(V)||isNaN(D)||V<=0||D<=0){
- $('vscTotalDisk').textContent='—';$('vscTotalRam').textContent='—';
- $('vscTotalDiskB').textContent='';$('vscTotalRamB').textContent='';
- $('vscDiskBD').innerHTML='';$('vscRamBD').innerHTML='';
- $('vscDiskChart').innerHTML='';$('vscRamChart').innerHTML='';
- $('vscCluster').style.display='none';$('vscFormulas').textContent='';return;
+ clearOutputs();return;
}
if(D>4096){
+ clearOutputs();
w.classList.add('vsc-visible');
wm.innerHTML='Elasticsearch supports a maximum of 4,096 dimensions for dense_vector fields. <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-params" target="_blank" rel="noopener">See documentation</a>.';
return;
}
@@
- var noteEl=$('vscNote');📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if(isNaN(V)||isNaN(D)||V<=0||D<=0){ | |
| $('vscTotalDisk').textContent='—';$('vscTotalRam').textContent='—'; | |
| $('vscTotalDiskB').textContent='';$('vscTotalRamB').textContent=''; | |
| $('vscDiskBD').innerHTML='';$('vscRamBD').innerHTML=''; | |
| $('vscDiskChart').innerHTML='';$('vscRamChart').innerHTML=''; | |
| $('vscCluster').style.display='none';$('vscFormulas').textContent='';return; | |
| } | |
| if(D>4096){ | |
| w.classList.add('vsc-visible'); | |
| wm.innerHTML='Elasticsearch supports a maximum of 4,096 dimensions for dense_vector fields. <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-params" target="_blank" rel="noopener">See documentation</a>.'; | |
| return; | |
| } | |
| var noteEl=$('vscNote'); | |
| function clearOutputs() { | |
| $('vscTotalDisk').textContent='—';$('vscTotalRam').textContent='—'; | |
| $('vscTotalDiskB').textContent='';$('vscTotalRamB').textContent=''; | |
| $('vscDiskBD').innerHTML='';$('vscRamBD').innerHTML=''; | |
| $('vscDiskChart').innerHTML='';$('vscRamChart').innerHTML=''; | |
| $('vscCluster').style.display='none';$('vscFormulas').textContent=''; | |
| noteEl.style.display='none'; | |
| } | |
| if(isNaN(V)||isNaN(D)||V<=0||D<=0){ | |
| clearOutputs();return; | |
| } | |
| if(D>4096){ | |
| clearOutputs(); | |
| w.classList.add('vsc-visible'); | |
| wm.innerHTML='Elasticsearch supports a maximum of 4,096 dimensions for dense_vector fields. <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-params" target="_blank" rel="noopener">See documentation</a>.'; | |
| return; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/vector_sizing_calculator/embed.html` around lines 428 - 439, The
early-return paths do not clear the same UI state as the initial validation
block, so stale results remain when D>4096 (and other invalid inputs) trigger a
return; update the D>4096 branch (and any other early-return branch) to call the
same UI-reset steps used when isNaN(V)||isNaN(D)||V<=0||D<=0 — i.e., reset
$('vscTotalDisk'), $('vscTotalRam'), $('vscTotalDiskB'), $('vscTotalRamB'),
$('vscDiskBD'), $('vscRamBD'), $('vscDiskChart'), $('vscRamChart'), clear
$('vscFormulas').textContent and hide $('vscCluster') before showing the warning
via w.classList.add('vsc-visible') and setting wm.innerHTML; ensure the reset is
applied consistently wherever the function returns early.
| <select id="indexType"> | ||
| <option value="hnsw">HNSW</option> | ||
| <option value="flat">Flat (brute-force)</option> | ||
| <option value="disk_bbq">DiskBBQ</option> | ||
| </select> |
There was a problem hiding this comment.
Block unsupported disk_bbq states in the standalone preview.
Line 397 always exposes disk_bbq, and Lines 581-603 only re-sync quantization. That lets this page calculate byte/bit + disk_bbq, even though both React calculators only allow disk_bbq for float/bfloat16. The inline path also never rejects bbqVpc <= 0, so Line 707 can produce Infinity results. This preview URL will otherwise disagree with the shipped calculator on valid inputs and outputs.
Also applies to: 572-640, 707-714
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/vector_sizing_calculator/index.html` around lines 394 - 398, The
standalone preview must mirror the React calculators: block selecting "disk_bbq"
in the indexType select unless quantization is "float" or "bfloat16", so update
the indexType handling (select id="indexType") and the preview recalculation
path (e.g., the function that computes byte/bit/preview results) to disable or
remove the "disk_bbq" option when quantization is not float/bfloat16 and
re-select a valid index if needed; additionally validate the bbqVpc input
(bbqVpc) to require > 0 and short-circuit the calculation (return an error/skip
and avoid computing Infinity) when invalid, and ensure any quantization change
handler also re-sync indexType state so the inline preview cannot compute
bit/byte + disk_bbq combinations that the shipped React calculators disallow.
| | Dimensions | No quantization | `int8` | `int4` | `bbq` | | ||
| | --- | --- | --- | --- | --- | | ||
| | 384 | 1,600 B/vec | 388 B/vec (4.1×) | 196 B/vec (8.2×) | 62 B/vec (25.8×) | | ||
| | 768 | 3,136 B/vec | 772 B/vec (4.1×) | 388 B/vec (8.1×) | 110 B/vec (28.5×) | | ||
| | 1,024 | 4,160 B/vec | 1,028 B/vec (4.0×) | 516 B/vec (8.1×) | 142 B/vec (29.3×) | | ||
| | 1,536 | 6,208 B/vec | 1,540 B/vec (4.0×) | 772 B/vec (8.0×) | 206 B/vec (30.1×) | | ||
|
|
||
| :::{note} | ||
| Bytes per vector include HNSW graph overhead (64 bytes with `m = 16`). Reduction factors compare total per-vector RAM (vectors + graph) against the unquantized baseline. | ||
| ::: |
There was a problem hiding this comment.
Correct inconsistent RAM math assumptions in the quick-reference table.
Line 334 says values include HNSW graph overhead (+64 bytes), but the quantized entries at Lines 328-331 match quantized vector bytes only (for example, 384-dim int8 is shown as 388, not 452). This makes the reduction factors inconsistent with the stated formula basis and can misstate sizing guidance.
Please align the table values/factors and the note to one consistent definition before merge.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/vector_sizing_calculator/sizing-section.md` around lines 326 - 335, The
table's quantized column values and reduction factors are inconsistent with the
note that says "Bytes per vector include HNSW graph overhead (+64 bytes)"; fix
by choosing one canonical definition and applying it consistently: either (A)
add the 64-byte HNSW overhead to every quantized value (e.g., change 384-dim
int8 from 388 B/vec to 452 B/vec) and recompute the reduction factors vs the
unquantized baseline, or (B) change the note to state that the table shows
quantized vector bytes only (exclude the 64 B graph overhead) and update the
reduction factors to compare vector-only sizes; update the rows for Dimensions
(384, 768, 1024, 1536) and the reduction factor parentheses accordingly so all
values and the note use the same basis.
Add the React + EUI web component, directive examples, and integration docs under tools/vector_sizing_calculator to stage migration into docs-builder.