draft extract dimensions nooa - #1169
Draft
mborodii-prog wants to merge 2 commits into
Draft
Conversation
11 tasks
mborodii-prog
requested review from
ebhills and
thomasstvr
and removed request for
ebhills
September 8, 2026 15:08
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add extract.dimensions, an AI-powered wrangle built on NOOA
Summary
Adds
extract.dimensions, a new wrangle for extracting structured dimensional measurements (length, width, height, diameter, depth, explicitly-stated volume, and labeled misc measurements like thickness, radius, bore, area, clearance, gauge) from messy product text.This is also a prototype evaluation of NVIDIA's NOOA agent framework (
nooa==0.0.10) as a lightweight alternative to this repo's existing raw-HTTPextract.aiimplementation, for cases where a single typed Predict call (no tool-use loop) is enough.Examples
Python API
Output shape - one
{"measurements": [...]}object per input row, in thesame order as the input:
{ "measurements": [ { "kind": "diameter", "label": null, "value": 3.2, "minimum": null, "maximum": null, "unit": "in", "qualifier": "outside", "source": "3.2 in OD" } ] }A range (instead of a single value) leaves
valuenull and populates bothminimumandmaximum:{"kind": "width", "value": null, "minimum": 12, "maximum": 14, "unit": "in", "source": "12-14 in wide"}Compact
L x W x Hgroups produce one measurement per dimension:{ "measurements": [ {"kind": "length", "value": 18, "unit": "in", "source": "18 x 14 x 8 in"}, {"kind": "width", "value": 14, "unit": "in", "source": "18 x 14 x 8 in"}, {"kind": "height", "value": 8, "unit": "in", "source": "18 x 14 x 8 in"} ] }A
miscmeasurement always carries a descriptivelabel:{"kind": "misc", "label": "thickness", "value": 0.75, "unit": "in", "source": "3/4 in thick"}Input with no supported dimensional fact returns an empty list:
{"measurements": []}Recipe API
input: one column, several columns, or omitted (uses every column).A single column's raw values are used as-is; multiple columns are combined into one record per row.
output: exactly one column, holding the whole{"measurements": [...]}object per row - unlikeextract.ai, there'sno
output_format(columns/concatenate/dictionary) mode, since an open-ended measurements list doesn't map cleanly onto fixed output columns the wayextract.ai's per-field schema does.What's explicitly out of scope
Design notes
nooa==0.0.10; python_version >= "3.12"lives only inrequirements-full.txt- a plainpip install wranglesnever installs it, and a plainimport wranglesnever importsnooaorlitellm.wrangles/nooa_client.pydefers every NOOA import to inside functions, memoized behind a lock so it happens once.import nooaunconditionally importsfcntl(POSIX-only) via its SQLite storage backend, and registers aSIGUSR2handler that doesn't exist on Windows'signalmodule._ensure_windows_guard()stubs just enough of both to let import succeed, without enabling real file locking or Unix signal handling (not needed - this integration only uses the default in-memorymevent store). Full writeup:docs/explain_extract_dimensions_nooa.md.PredictStrategyalready retries internally on invalid structured output (PredictConfig.max_retries, raisingGenerationErrorafter exhausting) - confirmed by reading NOOA's own source, not assumed.batchwrangle already uses: submit each row's future in original order, collect results by that same list order (not completion order).extract.ai's per-row error-stringbehavior. This is an explicit prototype-scope limitation, not an oversight (see the original issue's "Intentional boundaries").
extra="forbid") with amodel_validatorenforcing the value/range shape (exactly one ofvalueorminimum+maximum) and thatmiscmeasurements carry a label.Tests
tests/test_nooa_extract_dimensions.py- fully offline, three tiers: pure Pydantic contract tests (no nooa needed), plumbing tests mocking thenooa_clientboundary (row order, bounded concurrency, empty input, missing-dependency error, base-import-unaffected), and 2 tests against the real installed nooa package using its ownFakeLLMClient, guarded withpytest.mark.skipif(importlib.util.find_spec('nooa') is None, ...). Verified end-to-end by actually installingnooa==0.0.10in an isolated venv and running the suite against it (both real-nooa tests pass) - and separately confirmed clean skipping in the normal, nooa-less venv.tests/recipes/wrangles/test_extract_dimensions.py- recipe-YAML wiring only (input column handling, output shape), fully mocked.schema/generate_recipe_schema.pyrun successfully in a venv with no nooa installed, confirming the new wrangle's docstring is valid and this step never needs nooa.Flagged for reviewer attention
output_formatmodes on the recipe wrangle (single output column only) - deliberate simplification, not a missing feature.setup.pyextras_require- followed this repo's existing precedent (every other optional dependency is requirements-file-only + lazy-loaded), rather than introducing a first-of-its-kindpip install wrangles[nooa]mechanism.api_baseparam added to both the plain function and the recipe wrangle, beyond the original issue's literal examples, for parity with NOOA'sget_llm_client(..., api_base=...)andextract.ai'surloverride.