Skip to content

fix: build the vendor tree from uv.lock and raise the libbs floor - #179

Merged
vgoat21 merged 5 commits into
chore/auto-bump-revengaifrom
fix/vendor-lock-drift
Oct 20, 2026
Merged

vgoat21 merged 5 commits into
chore/auto-bump-revengaifrom
fix/vendor-lock-drift

Conversation

@vgoat21

@vgoat21 vgoat21 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Stacked on #178 (chore: bump revengai to 4.72.2). Merge #178 first, or retarget this to main once #178 lands.

Why

reai_toolkit/vendor/ is what the plugin actually imports — both reai_toolkit_entry.py:8-30 and tests/conftest.py:26 prepend it to sys.path ahead of site-packages. build_vendor.sh resolved it with uv pip install ., which ignores uv.lock and re-resolves from the pyproject.toml floors. The result was three different dependency realities:

package uv.lock vendor/ (ships) .venv (tests)
revengai 4.72.2 4.20.0 4.20.0
libbs 2.16.5 3.8.1 2.16.5
pydantic 2.12.3 2.13.5 2.12.3
urllib3 2.6.3 2.7.0 2.6.3

Because conftest.py prepends the vendor tree, every test run to date resolved the vendored 4.20.0 — verified with a probe test that printed v4.20.0 under the real conftest. The SDK bump in #178 was never actually exercised by CI.

What

  • build_vendor.sh now exports the locked runtime set (uv export --frozen --no-dev --no-emit-project) and installs that, so the shipped tree is reproducible from uv.lock.
  • New scripts/check_vendor.py asserts the vendor tree matches uv.lock and is run on every rebuild. Environment markers are evaluated, so Windows-only pins (colorama, win32-setctime) aren't reported missing on macOS. Worth wiring into CI as a standalone gate.
  • Raise the libbs floor to >=3.8.1.

On the libbs floor

The lock sat exactly on the old >=2.16.5 floor. That version's libbs/decompilers/ida/compat.py:30 does a bare import ida on the non-interactive path, which does not resolve under IDA 9.3 idalib — so once the vendor tree was built honestly from the lock, 27 test modules failed at collection. 3.8.1 is what the drifted tree had been shipping all along, so this pins the version that actually works rather than changing behaviour.

Note libbs is EOL at 3.8.1 — it is now a sys.meta_path shim forwarding to declib (4.5.0), and it warns it will be removed. Migrating the ~30 files that import libbs over to declib is worth a follow-up, but is deliberately not in this PR.

Verification

With the vendor tree correctly built from the lock, the suite is green against revengai 4.72.2 for the first time:

511 passed, 3 skipped in 10.81s

(IDADIR=/Applications/IDA Professional 9.3.app/Contents/MacOS, uv run pytest.) A probe under the real conftest now reports PROBE= v4.72.2.

🤖 Generated with Claude Code

The vendor tree under reai_toolkit/vendor is what the plugin actually
imports: both reai_toolkit_entry.py and tests/conftest.py prepend it to
sys.path ahead of site-packages. build_vendor.sh resolved it with
`uv pip install .`, which ignores uv.lock and re-resolves from the
pyproject floors, so the shipped tree drifted away from the lockfile --
revengai 4.20.0 vendored against 4.72.2 locked, libbs 3.8.1 vendored
against 2.16.5 locked. Every test run to date resolved the vendored
4.20.0, so the SDK bump was never actually exercised.

Export the locked runtime set and install that instead, and add
scripts/check_vendor.py to assert the tree matches uv.lock (environment
markers evaluated, so Windows-only pins are not reported missing on
macOS). build_vendor.sh now runs the check on every rebuild.

Raise the libbs floor to 3.8.1. The lock sat on the 2.16.5 floor, whose
decompilers/ida/compat.py does a bare `import ida` on the headless path
and fails to import under IDA 9.3 idalib; 3.8.1 is what the drifted tree
had been shipping, so this codifies the working version rather than
changing it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vgoat21
vgoat21 requested a review from a team as a code owner October 20, 2026 09:10
vgoat21 and others added 2 commits October 20, 2026 10:33
revengai 4.72.2 tightened the pydantic constraints on two models the plugin
constructs by hand:

  FunctionBoundary.mangled_name   StrictStr -> min_length=1, max_length=4096
  FunctionBoundary.start_address  StrictInt -> ge=0
  FunctionBoundary.end_address    StrictInt -> ge=0
  Symbols.base_address            StrictInt -> ge=0
  Symbols.function_boundaries     List      -> max_length=200000

collect_symbols_from_ida fed idc.get_func_name() straight into mangled_name.
That returns "" for an unnamed function, which now fails min_length=1 and
raises ValidationError out of the whole collection pass -- so upload would
break outright on any binary containing one. The boundary list was also
unbounded, and a negative image base would trip ge=0.

Skip boundaries with no name rather than inventing one, truncate over-long
names, clamp the base address, and cap the list, warning when either the skip
count or the cap is non-zero so the truncation is not silent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
revengai 4.72.2 marks 85 operations deprecated, up from 25. Eight of the nine
the plugin called now emit a DeprecationWarning at call time and have a v3
successor; this moves them over.

Every v2 operation returned a BaseResponseX envelope with a .data attribute.
Every v3 operation returns a flat *OutputBody. So each migration is: swap the
method, drop the .data unwrap, remap fields.

  ConfigApi.get_config                  -> ConfigApi.v3_get_config
  AnalysesCoreApi.get_analysis_status   -> AnalysesCoreApi.v3_get_analysis_operation
  AnalysesCoreApi.get_analysis_function_map
                                        -> FunctionsCoreApi.v3_get_analysis_func_maps
  AnalysesCoreApi.list_analyses         -> AnalysesCoreApi.v3_list_analyses
  AnalysesCoreApi.upload_file           -> BinariesApi.v3_upload_file
  SearchApi.search_binaries             -> BinariesApi.v3_search_binaries
  SearchApi.search_collections          -> CollectionsApi.v3_list_collections
  FunctionsAIDecompilationApi.upsert_ai_decompilation_rating
                                        -> ..._api.v3_upsert_ai_decompilation_rating

Notes on the non-obvious ones:

SearchApi is now deprecated in its entirety -- it has zero non-deprecated
operations. Binary search moves to GET /v3/binaries and collection search to
GET /v3/collections; both swap page/page_size for limit/offset.
CollectionListItemBody renames six fields off CollectionSearchResult
(scope, last_updated_at, created_at, owned_by, tags, size).

Analysis status moves to the long-running-operation endpoint
GET /v3/operations/analyses/{analysis_id}, whose CreateMetadata.status carries
the same platform status string v2 returned, so the Complete/Error state
machine is unchanged.

v3_upload_file drops packed_password. That parameter was dead plumbing here:
declared and threaded between _upload_file_req and upload_user_file but never
supplied by any caller. Archive passwords moved to the sandbox side of the
platform (SandboxConfig.archive_password), so it is removed rather than
reimplemented.

Also handle the types_applied AI-decompilation stream event, new in 4.72.2 as
the EventTypesApplied oneOf variant. The hand-rolled SSE parser keys off event
names and had no branch for it, so those events were dropped silently.

AnalysesCoreApi.create_analysis stays on v2: POST /v2/analyses is deprecated
but has no v3 successor in the live v4.73.0 spec. It is now the only deprecated
SDK call left in the plugin. The remaining /v2 calls -- IAMUsersApi.get_me and
the seven ConversationsApi operations -- are not deprecated and have no /v3
paths in the spec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
refactor: migrate the deprecated v2 endpoints onto v3
fix: guard symbol collection against 4.72.2 validation constraints
@vgoat21
vgoat21 merged commit be61770 into chore/auto-bump-revengai Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant