Repository navigation
InferBridge 0.9.5
InferBridge 0.9.5
This is a full release, not a pre-release. It supersedes 0.8.0 as the current
stable version.
Its artifacts are unsigned. Windows reports an unknown publisher and SmartScreen may warn
on first launch. Nothing in this release has been Authenticode signed, and no signing claim is
made anywhere in its metadata. Verify downloads against the published SHA-256 checksums. A
signed build will have to advance the version, because published tags and assets are immutable.
Everything below shipped only as 0.9.x pre-releases until now. 0.9.0 through 0.9.3 were never
published as stable, and 0.9.0 was written as a planned stable record that no tag
ever carried; 0.9.5 is the release that actually delivers that content to the stable channel.
The code in this release is the code from 0.9.3-beta.2 with no functional change. The only
source differences are in test and lint hygiene, described under
Release gate below.
Model preparation is transactional
A conversion that was cancelled, ran out of disk, or was interrupted by an upgrade could leave
partially written OpenVINO output in the live model directory, and that output was then treated
as a converted model.
- Exports are staged, then published. Conversion writes into a sibling staging directory,
the result is validated, and only then does it replace the live directory, through a bounded
backup and rollback window. A previously working model survives a failed or cancelled
reconversion. - Publication is hardened for Windows. Replacement retries transient sharing violations and
access denials rather than failing on the first antivirus or Explorer lock, and clears
read-only attributes it encounters. - Packaged conversions run inside the same transaction. The packaged converter path
previously bypassed staging; conversions launched from the installed or portable build now get
the same guarantee as source runs. - Preparing the same model twice is blocked across processes. An installed instance and a
portable one could previously convert the same model into the same directory simultaneously.
Preparation now takes a cross-process lock on the output directory, and the second process
fails fast telling you to wait or close the other instance.
Incomplete model directories are no longer treated as models
A partially written export can contain an IR XML file before its weights or configuration are on
disk. That directory previously counted as downloaded, so retries skipped conversion and handed
an incomplete artifact to the native OpenVINO loader.
- One shared readiness check in
runtime/model_artifacts.pyvalidates that the IR XML is a
complete document, that its paired weights file exists and is non-empty, and that the model
configuration is present and parseable. Catalog, recovery, and load paths all use it, so they
can no longer disagree about whether a model is ready. - The check stays cheap. It probes bounded regions of the IR XML rather than parsing
multi-gigabyte files, so catalog listing is not slowed down. - Recovery classifies staged output correctly. Interrupted staging is reported as recoverable
output instead of being missed, and recovery cleans it up.
Symbolic links and Windows junctions are refused
Deletion and recovery cleanup previously followed reparse points, so a model directory that was
really a junction could have caused deletion outside model storage. Junctions are invisible to
is_symlink(), so link detection now reads file attributes directly.
- Model deletion refuses to act through a symbolic link or junction and asks you to remove the
link manually after confirming its target. - Recovery cleanup refuses the same, refuses paths that are not directories, and refuses staged
paths that fall outside the configured model directory.
Installing over an existing installation, and uninstalling, both work
Two reported installer defects had one cause: the tray launcher and its server child are
windowed processes with no top-level window, so Restart Manager had nothing to send a close
message to and reported that applications could not be shut down. Nothing else stopped the
application, so upgrade failed on locked files and uninstall left files behind while reporting
success.
- Setup and the uninstaller stop a running instance before touching any file.
PrepareToInstallandInitializeUninstalldetect a live instance through its lock file, ask
it to exit through its own tray command file, and wait up to 15 seconds. - An instance that will not exit is terminated. Termination is reached only while the
installed instance still holds its lock, so an unrelated portable instance is normally
untouched. - The tray honours an external quit request. The command-file handler previously only set the
stop event, ending the status poller while the tray message loop kept running and kept holding
installation files. It now performs the same full shutdown as the tray menu's Quit. - Uninstall removes what it previously left behind — compiled Python caches and anything left
by an interrupted upgrade — with attribute clearing and bounded retries, then removes the
emptied program directory. - Uninstall reports what it could not remove. Every removal result is checked and any
surviving path is named, instead of being discarded while the uninstaller claims success. - Start with Windows is removed on uninstall. The
Runentry previously survived, so Windows
kept trying to launch a deleted executable at every logon.
Packaged model conversion works
The installed and portable builds of 0.9.3-beta.1 and earlier could not prepare any model.
Every conversion failed with Conversion failed: could not get source code seconds in, before a
single byte was downloaded, while the same conversion succeeded from a source checkout.
- The bundle ships Python sources for the conversion packages.
optimum-cli export openvino
importsoptimum.intel.openvinofirst, which applies a Transformers decorator that reads its
decorated function's source withinspect.getsource, andimport torchtokenizes its own
configuration modules the same way. Shipping only bytecode meantlinecachefound no lines and
Python raisedOSError. This adds roughly 9 MB. - Release validation imports the export chain. The packaged smoke test previously walked only
Optimum's CLI registration namespace, which never imports Optimum Intel, so the build passed
while every conversion was broken. A missing source file now fails the build instead of the
user's first download. - Long packaged downloads no longer fail mid-flight.
tqdmand the Transformers loader
redrew on the helper's stderr with carriage returns and no newline, and the server reads that
pipe withasyncio.StreamReader.readline, which raises once its 64 KiB buffer fills without a
separator. In-process Optimum output is now split into whole lines. - Packaged conversions report real progress. Download and quantization percentages reach the
UI instead of one static "Running packaged OpenVINO conversion…" message for the whole export. - Packaged Optimum CLI discovery is gated at build time. The build now requires the packaged
Optimum CLI to actually discover the OpenVINO export command through the same namespace scan
the CLI uses; bundling the registration module is not sufficient if PyInstaller leaves it
outside that scan. - The OpenVINO tokenizer runtime is bundled and packaged DLL search paths are registered.
Tokenizer runtime failures are classified distinctly, and a tokenizer packaging fault no longer
triggers pointless retries against other devices. - Frozen helper failures name their origin. A windowed helper cannot show a traceback, so
failures now report the exception type and the originating file and line, with no bundle path
included.
Device switches no longer interrupt the loaded model
Switching a loaded model to another device previously took the model's lock before compiling the
replacement, so the model was unavailable for the entire compilation.
- The loaded engine stays usable while the replacement compiles. The lock is taken only for
the short handoff at the end, and it is re-validated in case the engine was replaced while
waiting. - The catalog reports the switch honestly. A loaded model that is switching devices is shown
as loading and cannot be unloaded, instead of appearing idle and unloadable. - Unload is rejected during a switch, which previously raced the load task. Shutdown can
still force cleanup after its generation drain timeout.
Model preparation recovery
- Persists sanitized recovery state after interrupted, cancelled, or failed conversion and
loading operations, and distinguishes reusable Hugging Face source cache data from incomplete
or complete OpenVINO conversion output. - Adds a WebGUI recovery screen with resume, failed-stage retry, fresh-download restart,
incomplete-output cleanup, and sanitized failure details. - Keeps recovery actions operation-scoped with stale recovery-ID rejection behind the existing
API-key and browser-origin protections, and refuses to remove complete models, symbolic links,
paths outside the configured model directory, or the model-directory root. - Preserves stream cancellation precedence when a cancellation and a recovery race.
- Cleanup is resilient on Windows. Transient
rmtreefailures retry with a bounded backoff,
the read-only attribute is cleared before retrying, symbolic links are checked before existence
so a dangling link is refused rather than treated as an absent directory, and a cleanup that
cannot complete raises a bounded, actionable conflict naming no local path while preserving the
recovery record.
See Model preparation recovery for the recovery contract and API.
Stage-aware preparation watchdogs
- Separate download, conversion, finalization, loading, and OpenVINO compilation limits.
- Inactivity detection for download, conversion, and finalization, so a slow operation stays
valid while progress heartbeats continue; loading and native compilation use total stage
deadlines. - Reports the stalled stage and the last successful progress timestamp, and preserves reusable
cache data, incomplete conversion output, complete converted models, and any previously loaded
engine. - Keeps an external cancellation request intact when a watchdog timeout fires at the same time.
Context budget visibility
- An exact tokenizer-backed chat preflight for the selected loaded model, reporting prompt use,
context limits, output capacity, retained messages, pending attachment estimates, and the older
whole turns that will be omitted. - Reuses the generation path's message normalization, chat template, tokenizer, whole-turn
sliding window, and output safety allowance, so the preflight and the request agree. - WebGUI actions to preserve the current draft in a fresh chat or reduce the requested output to
the effective limit, with attachment preflight restricted to vision-capable models.
See Context budget visibility for calculation details and the API
contract.
Clearer conversion failures
- Disk exhaustion is named as such, with a note that cached downloads and any previously
working model are preserved where possible. - Windows file locking produces a message about closing other instances, Explorer windows,
and antivirus scans, rather than a rawWinError 32. - A concurrent preparation in another process is reported as exactly that.
- Repeated wrappers are collapsed, so errors no longer read
Conversion failed: RuntimeError: Conversion failed: …. - Converter diagnostics are bounded, so a converter that emits a large volume of output no
longer grows memory without limit.
Interface, desktop, and tray
- The release and update panel works. A missing closing parenthesis in the injected release
script meant the browser refused to parse that entire<script>element, so the About and
update surface silently did nothing: no version or build detail, no update check, no download
link, and no signature statement. - The browser client ships valid markup. The custom-model modal was missing one closing
</div>,
so all 38 injected script and style elements were nested inside a hidden,aria-hiddenmodal
overlay instead of the document body. - The packaged launcher no longer aborts its own native validation when started without a
console. The frozen runtime hook gave up silently when it could not duplicate a standard
descriptor, leavingsys.stdoutandsys.stderrasNone; it now falls back to a discard
stream. - A packaged server startup exit surfaces immediately and readiness polling stops once the child
exits, and the resolved desktop data path is handed to the server child process. - Onboarding opens automatically only on the first WebGUI visit, its state recovery is atomic
through quarantine of an unreadable state file, and read-modify-write updates are serialized
under one lock. - Source and editable installs register with the
-m app.desktop_launcherdispatch, so Start
with Windows launches InferBridge rather than an idle interpreter. - Hardware-advisor telemetry moved off the request path while preserving its response contract.
- Active operation queue polish including progress-row accessibility, compact header overflow
menu keyboard behaviour and focus reliability, a safe Hugging Face search UI, and a fix for
stale workspace generation state. - Routine polling log noise is reduced while errors and slow requests are preserved.
- The tray tooltip, the private
/desktop/instancepayload, the model-library definition export,
and the API contract validator report the canonical product name instead of the former one.
Other fixes carried from the 0.9 line
- The update checker treated a published version equal to the installed version as an upgrade, so
the release that published the running build was offered as an available update on every check. - The preparation progress track reported every phase as determinate, so a phase with no
measurable percentage rendered a bar pinned at 0% instead of the indeterminate animation. - The monotonic overall-progress floor read an undefined property, producing
NaN, and was never
persisted across polls. - An
auto_convertload bounded the entire operation, including the nested download and
quantization, by a single ten-minute deadline, so preparing a multi-gigabyte model failed
mid-download. Only the native engine build is bounded now. - The authentication-failure map was pruned only for the requesting source, so it grew once per
distinct client address for the process lifetime. - Initial-load progress copy is accurate. "The currently loaded model remains available…" was
shown even when nothing was loaded yet; a first load now says "First load can take several
minutes…".
Release and build pipeline
- The pinned release environment is fingerprinted and cached so repeat builds reuse a validated
virtual environment. - The portable archive is built directly from the packaged tree instead of a staging copy, with
archive source parity verified. - Per-step release timing telemetry is published and timing provenance is required.
- Artifact scans are deduplicated and checksum generation is faster.
- Continuous integration parses every inline script in the fully composed browser page rather
than a hand-maintained list of ten, which is what allowed the release-panel defect to ship.
Companion tests assert the composed page's tag balance, unique element ids, and that injected
surfaces attach to the body. - A focused
Windows Model Lifecycleworkflow runs the download, convert, load, and recovery
regressions onwindows-latest, because most of that behaviour is Windows-specific and was
previously covered only on Linux. - Windows setup validates the supported Python version, the supported-version contract is aligned
across setup, preflight, and tests, an incremental developer package build was added, source
dependency profiles are recorded, and Hugging Face tokens are kept out of setup files.
Release gate
Unlike the 0.9.x pre-releases, this build was not produced with -SkipTests. Ruff lint,
Ruff formatting, the full Python test suite (839 passed, 3 skipped), the external mock API
contract validator, and the packaged installed-mode and portable-mode mock smoke tests all ran as
part of the release build and passed.
Getting there required three test-and-lint fixes, which are the only source changes in this
release relative to 0.9.3-beta.2:
tests/test_lifecycle_delete_safety.pyhad an unsorted import block that failedruff check,
and five files had drifted fromruff format. Reformatting touchedapp/errors.py,
app/model_recovery_cleanup.py,app/structured_progress.py, andruntime/model_artifacts.py
with line-wrapping changes only, with no change in behaviour.tests/test_model_recovery_cleanup.py::test_incomplete_output_rejects_a_dangling_link_before_exists_check
fakedis_symlink()on a path it never created._is_reparse_pointcallslstat()first and
returnsFalsewhen that raises, so the fake never reached the branch under test and the guard
correctly declined to fire. The fixture now models a dangling link's actual observable
behaviour —lstat()succeeds, no reparse attribute,is_symlink()true,exists()false —
so it exercises the guard rather than contradicting it. The shipped guard was never wrong.tests/test_model_load_target.py::_wait_for_load_tasksampled the model entry before
checking whether the load task had settled, then returned that stale sample. A task completing
in that window produced an entry predating its own final status and progress update, which made
test_failed_device_switch_keeps_the_working_engine_availablefail intermittently under full
suite load. The helper now reads the entry only after confirming the task settled.
Release provenance, the model library manifest, and SHA-256 checksums are verified independently
of the build.
The upgrade and uninstall paths were exercised on Windows 11 build 26200 against a real
installation with the application running, reproducing the reported failures first and confirming
they no longer occur: installing over a running earlier release completed with no "unable to
automatically close all applications" prompt, replacing all 6,309 program files; uninstalling with
the application running reported Removed all? Yes, left no program files behind, ended both
processes, and removed the Start Menu shortcut and the uninstall registry entry.
Packaged model conversion was verified against a real packaged build by driving the installed
application's own HTTP API with no mock: tinyllama-1.1b-chat-int4 downloaded, converted to INT4
OpenVINO IR, loaded, and generated a completion.
Not verified
- Authenticode signing. These artifacts are unsigned. The documented process reserves the
stable channel for signed artifacts; this release was published to it unsigned by explicit
decision, and its unsigned status is stated in its metadata, its notes, and the README. - Real Intel CPU, GPU, or NPU execution, which requires the Windows certification harness on
suitable hardware with mock mode disabled. - Installer upgrade and downgrade beyond the scenario above, including upgrade from every
historical release and uninstall with a conversion in progress. - Tokenizer behaviour for every converted model, conversion of models other than the one
exercised above, and recovery behaviour with every Hugging Face cache and checkpoint layout. - Conversion behaviour against real disk-full and antivirus-lock conditions rather than simulated
ones. - The "remove user data" branch of the uninstall prompt interactively; a silent uninstall takes
the documented default of keeping user data. - Four Chromium browser tests under
browser_tests/fail and also failed at thev0.9.2-beta.1
tag. They are outside thepytestrelease gate, whosetestpathsistests.