Skip to content

Releases: JaredP94/Personal-AI-Router

Personal AI Router 0.8.0 — macOS Apple Silicon

Choose a tag to compare

@JaredP94 JaredP94 released this 02 Nov 11:39
2aecf6d

Personal AI Router 0.8.0 — macOS Apple Silicon

Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0 installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default. Earlier releases remain on the releases page.

Upgrade notes

  • Versions: Desktop 0.8.0 ships service product 2.6.0, with nvpair-node-info and nvpair-engine-manager at 1.3.0. The relay envelope protocol stays v2, so upgrade desktop/TUI and services together.
  • Compatibility: no JSON-RPC method was removed. engine:install-tool, engine:remote-install-tool and the /v1/node-info sensors object are additive.
  • Mixed clusters: installing macmon on a remote peer needs that peer on engine-manager 1.3.0 or newer. An older peer answers with a generic error; install macmon on it by hand, or upgrade it first.
  • macmon: it is a Homebrew dependency PAIR can install for you. It is not bundled, and macmon's own licence (MIT) is not part of this package.

What this release adds

Sensors on Apple Silicon node cards

  • Sensors drawer. A new thermometer button on Apple Silicon node cards opens four tiles:
    • Temperature: the hotter of CPU and GPU, both shown underneath.
    • Fans: each fan's speed against its maximum.
    • Power: system watts, with the CPU, GPU and Neural Engine split.
    • Memory: the memory pressure level, with swap use.
  • Badges. The collapsed card shows Throttling when macOS reports thermal pressure above nominal, and Memory pressure at warning or critical. Colour comes only from macOS's own pressure levels; Apple publishes no safe temperature limits, so temperatures are never coloured.
  • Install macmon from the card. Temperature, fan and power readings come from macmon, which reads Apple's sensors without sudo. When it is missing, the drawer offers Install macmon, which runs brew install macmon on this machine or on a trusted cluster peer. Without Homebrew, it shows the command to copy instead.
  • No macmon needed for thermal pressure, memory pressure and swap, which PAIR reads directly.
  • Nothing is fabricated. An unmeasured reading shows "—", never 0, and a fanless Mac reads "No fans".
  • Display-only: sensor readings don't change scheduling or routing.

Aligned metrics layout

  • Key/value groups. Node cards, job cards and the performance legend show their metrics as aligned key/value groups. Each group names its window once ("Last 60 s", "Since broker start", "This request", "Engine total", "Engine average").
  • Formatting. The per-model breakdown is a table, values use tabular figures, and an unreported value reads as a muted dash.
  • Keyboard access. Legend rows are buttons, so soloing a series works from the keyboard.

Full list: CHANGELOG.

Validation

Built from 2aecf6d (merge of the release-prep PR #23) on a clean tree. Its tree is identical to the gated release-prep commit 54eff56.

  • Repository gate: make check and make test pass. That covers 726 desktop unit tests, every Go module, and the cross-process suite in services/tests. The cross-process suite failed 15 tests at the 0.7.0 build only because a running PAIR app held its ports; no app was running this time.
  • Release checks:
    • npm run dead-code:check and npm run licenses:check pass (298 dependencies attributed).
    • SPDX headers pass.
    • scripts/install-mac.sh passes bash -n and shellcheck, and its 95 installer tests pass.
  • Race detector: go test -race passes in node-info and engine-manager.
  • Skipped tests (untested, not passing): five Go tests skip on the build machine. Four engine-manager tests can't resolve which process owns a port, and one live oMLX test skips.
  • Feature review: the sensors feature was reviewed per task, then as a whole branch by an independent model (two passes), before merge (#22).
  • Live check of the feature in the desktop app on an Apple M5 Max (macOS 27.2):
    • The local card's drawer showed real readings, with no badges.
    • After brew uninstall macmon and the running macmon process exiting, node-info reported missing with no zeroed values. The card offered Install macmon, and the Memory tile kept working.
    • Clicking Install macmon finished in about 11 s, and readings were back on the card at 12 s with no restart.
  • Package checks:
    • Versions: the app reports 0.8.0. All 14 bundled service binaries report their services/versions.json versions and are arm64-only, and the bundled manifest reports product 2.6.0.
    • Sensors in the shipped build: the packaged nvpair-node-info served live sensors and exited cleanly with its macmon child.
    • Licences: LICENSE, LICENSE.electron.txt, LICENSES.chromium.html and THIRD_PARTY_NOTICES.md are present in the packaged app.
    • Contents: the app inside the DMG and inside the ZIP is identical to the built bundle (content-manifest SHA-256 ce52ed9e21cf955d7eb953d505ea675f9a4d51d057da57897cc30b0066a3b54c, 291 files). service-binaries-mac-arm64.zip matches the bundled cli-bin.
    • Checksums:
      • NVPAIR-Setup-0.8.0-arm64.dmg: SHA-256 101d1d852797f9b9dc5c4716a885a71a312f51c9c14e8dff3d49929fcb617066
      • NVPAIR-Setup-0.8.0-arm64.zip: SHA-256 96b2ddef52482123aa53f86f2ec6eb0096efb9c145404e6f7056e36893461f8b
      • service-binaries-mac-arm64.zip: SHA-256 33e19cbaa7af51c2026aac26744a12f6e92a76aff1e4cc59aeedf1815f8da9e8
    • Signing and updates: the update feed points at this fork. Code signing is ad-hoc only.

Assets

  • NVPAIR-Setup-0.8.0-arm64.dmg and .zip, with their blockmaps.
  • service-binaries-mac-arm64.zip: the packaged service binaries.
  • SHA256SUMS.
  • The macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • Remote install: installing macmon on a remote cluster peer from the card was not tested live, because no second Mac was in the cluster. It is covered by engine-manager unit tests, including the pin gate and error-code round trip.
  • Packaged app: a full launch of this packaged app (the live check above used the development build from the same commit). Also not validated: fresh install on a new machine, upgrade from 0.7.0 on a live machine, uninstall, purge, and corrupt- or interrupted-download handling.
  • Fanless hardware: sensor behaviour on fanless Macs and on chips other than the M5 Max. macmon's output can differ between chips and macOS releases; PAIR reads only its stable fields, and anything unparseable shows "—".
  • Known minor follow-ups:
    • Thermal pressure can lag up to about 10 s when a card is opened after the node has been idle.
    • A node that stops answering keeps its last sensor readings, including badges, matching how CPU and GPU telemetry already behave.
  • Other platforms: Windows, Linux desktop and Intel Mac runtime.
  • Performance: no profiling of this build; no performance change is claimed.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.

v0.7.0-rc.5 — unsigned macOS arm64 candidate

Choose a tag to compare

@JaredP94 JaredP94 released this 22 Oct 10:59

Personal AI Router 0.7.0-rc.5 — macOS Apple Silicon candidate

Release candidate for the JaredP94 fork. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0-rc.4 installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default.

Upgrade notes

  • Desktop 0.7.0-rc.5 ships service product 2.4.1. The relay envelope protocol stays v2 and no JSON-RPC method was removed; the new broker method and the new node-record field are additive, so upgrade desktop/TUI and services together.
  • Mixed clusters: a member running an older workload-manager does not carry the engine-native view from remote nodes, so that view is complete only once every member is upgraded. The originating node is unaffected.
  • Per-node inference totals cover the period since the broker started, and reset when the broker restarts; per-job figures persist with the workload store.

Changes since 0.7.0-rc.4

Fixed

  • A manual peer's engine-native view was never fetched. The engine-native view — the engine's own counters, which 0.7.0-rc.4 added to the node card — was read only by the node-scanner, and only for the nodes in its own mDNS directory. A peer registered as a manual node (reached over Tailscale or a static address, not announced on the LAN) is never in that directory, so its record carried its model list but no engine counters, and the desktop showed nothing for it. nvpair-manual-nodes now reads the engine's own counters over the same pinned cluster-mTLS client it already used for the model list, and the broker projects them onto the manual node's record.
  • The fix was found by running the release against a live two-node cluster: the second node's counters are now identical to that machine's own engine counters (requests 2 / prompt tokens 123 / completion tokens 599, prefill 161.1 / generation 69.1 tokens per second).

From 0.7.0-rc.4 (unchanged here): the engine's own view on the node card, and live in-flight numbers on a running job — elapsed time, time to first byte, what has streamed, and for oMLX the engine's own token count, decode rate, prefill progress and queue position. No estimates: a chunk count is never shown as a token count, and a value nobody reported reads "not reported", never 0.

Full list: CHANGELOG.

Validation

Built from 41517a7 on a clean tree.

  • make check, npm run dead-code:check and make test pass: 625 desktop unit tests and every Go module, including the new nvpair-shared/inferencemetrics and nvpair-ui-broker/nodemetrics packages. go test -race is green in the broker, the workload-manager and the three inference proxies.
  • The change was reviewed three times before merge (per task, whole branch, and an independent final pass), and the fix in this release was verified against a live two-node cluster: a request served by the peer carried its measurement and its live frame back to the originating member under the right job id, and the per-job numbers matched the engine's own usage block exactly.
  • Package checks:
    • The app reports 0.7.0-rc.5, and the service binaries report their services/versions.json versions and are arm64-only.
    • LICENSE, LICENSE.electron.txt, LICENSES.chromium.html and THIRD_PARTY_NOTICES.md are present in the packaged app.
    • The DMG checksum is valid, and the app inside the DMG and the ZIP is identical to the built bundle (content-manifest SHA-256 9cb70b3fdfa7c26985cee5d53ad045c63c1f1909382cb555b9f188378ef9e31e).
    • NVPAIR-Setup-0.7.0-rc.5-arm64.dmg SHA-256 142d6325248220b66fd79cdd021e5feef728a01fef2721ebef5cc37f4201a2c0; NVPAIR-Setup-0.7.0-rc.5-arm64.zip SHA-256 0448e8da037322660e482d51d51154796ec7f85acb060e67bcaeaf971421e6e6; service-binaries-mac-arm64.zip SHA-256 9968fd4d3d5f93216d2d5ca4ece26d5311aee2be4453dcdf66b73caed439eeba.
    • The update feed points at this fork. Code signing is ad-hoc only.
  • The cross-process suite in services/tests fails 15 tests on the build machine because a running PAIR application holds ports 11434/1234/14320/14322. The identical failure set reproduces at the base commit, so it is an environment condition, not a regression.
  • No release-candidate profile was recorded for this build. The rc.3 profile in Performance and energy remains the most recent measurement; no percentage improvement is claimed.

Assets

NVPAIR-Setup-0.7.0-rc.5-arm64.dmg and .zip with their blockmaps, service-binaries-mac-arm64.zip (the packaged service binaries), SHA256SUMS, and the macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • The per-job phase durations need a newer oMLX, or a non-streaming request. oMLX 0.7.2's streaming usage chunk carries the token counts but not prompt_eval_duration, generation_duration or time_to_first_token; its non-streaming response does. Against 0.7.2 a streaming job therefore shows its token counts and reads "not reported" for the phase durations — the honest, designed behaviour.
  • The engine's live token count inside a progress frame was not observed end to end; the requests driven during validation were in prefill or model load.
  • Windows, Linux desktop and Intel Mac runtime; Windows worker-hang recovery and GPU readings.
  • Fresh install on a new machine, uninstall, purge, and corrupt- or interrupted-download handling of this build.
  • Upgrade from rc.4 on a live machine, and the profiling of this build.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.

v0.7.0-rc.4 — unsigned macOS arm64 candidate

Choose a tag to compare

@JaredP94 JaredP94 released this 22 Oct 07:59

Personal AI Router 0.7.0-rc.4 — macOS Apple Silicon candidate

Release candidate for the JaredP94 fork. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0-rc.3 installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default.

Upgrade notes

  • Desktop 0.7.0-rc.4 ships service product 2.4.0. The relay envelope protocol stays v2 and no JSON-RPC method was removed; the new broker method and the new node-record field are additive, so upgrade desktop/TUI and services together.
  • Mixed clusters: a node running an older workload-manager does not carry the new engine-native view from remote nodes, so that view is complete only once every member is upgraded. The originating node is unaffected.
  • Per-node inference totals cover the period since the broker started. The broker's accumulator is in memory, so the per-node figures reset when the broker restarts; per-job figures persist with the workload store.

Changes since 0.7.0-rc.3

The engine's own view

  • Each node's engine now reports its own counters — request and token totals, prefill and generation speeds, cache efficiency and loaded models — and PAIR carries them across the cluster and shows them on the node card. They are the engine's numbers, so they include traffic PAIR did not route; they are shown as a separate, labelled "engine self-report" and are never merged with PAIR's own totals.
  • The engine's API key cannot leak: PAIR defines its own response type and reads the engine's payload field by field, so the key the engine returns is dropped by construction.

Live in-flight numbers

  • A running job's card now shows what is happening now: elapsed time, time to first byte, how much has streamed, and — for oMLX — the engine's own token count, decode rate, prefill progress and queue position. 0.7.0-rc.3 showed nothing until a job ended, so a job stuck in prefill looked identical to one halfway through decoding.
  • No estimates. The live card shows what PAIR measures exactly and what the engine measures exactly. A chunk count is never presented as a token count, and no rate is derived from one. Anything nobody reported reads "not reported", never 0.
  • The live frames travel cluster-wide over the existing workload relay, rate-limited at the source, and each broker keys the live view by the origin node, the engine and the job id — because every proxy counts its own requests from one.

Housekeeping

  • The macOS installer no longer names a specific candidate version, and the release-profiling harness derives its candidate path from desktop/package.json instead of repeating the version.

Full list: CHANGELOG.

Validation

Built from 65864b610cdcd23b061016ff754dd080f1f77c57 on a clean tree.

  • make check, npm run dead-code:check and make test pass on the branch head: 625 desktop unit tests and every Go module, including the new nvpair-shared/inferencemetrics and nvpair-ui-broker/nodemetrics packages. go test -race is green in the broker, the workload-manager and the three inference proxies.
  • The change was reviewed three times before merge: a per-task review for each implementation task, a whole-branch review that returned four findings (all fixed), and an independent final review of the branch's last fix wave.
  • Live-engine checks against oMLX 0.7.2 (the version installed on the build machine):
    • oMLX emits its streaming usage block only when the request carries stream_options.include_usage, so the proxy's injection is load-bearing.
    • oMLX's /admin/api/stats payload matches what PAIR reads, and PAIR's parser read the live payload correctly (requests, token totals, cached tokens, cache efficiency, the loaded model, no error).
    • oMLX's /admin/api/activity payload is shaped {"active_models": {"models": [...]}}, which PAIR's parser did not understand — it read zero rows, so the live card would have shown no engine numbers with no error anywhere. Found by the live test and fixed, with a regression test.
    • Not yet verified end to end through PAIR itself: a live request through this build's proxy, the activity rows pairing with PAIR's job ids, and a live frame reaching a remote member's clients. The parsers are deliberately forgiving, so a shape mismatch shows as an empty view rather than an error.
  • Package checks:
    • The app reports 0.7.0-rc.4, and the service binaries report their services/versions.json versions and are arm64-only.
    • LICENSE, LICENSE.electron.txt, LICENSES.chromium.html and THIRD_PARTY_NOTICES.md are present in the packaged app.
    • The DMG checksum is valid, and the app inside the DMG and the ZIP is identical to the built bundle (content-manifest SHA-256 0d57d973a2b6af6ea915ca0c5165e4128b3e616cf2c09c36db19adb12a163c43).
    • NVPAIR-Setup-0.7.0-rc.4-arm64.dmg SHA-256 33678c73d063b929a05c940e2aac7994f734112b9a6d05843a131c37f41b597c; NVPAIR-Setup-0.7.0-rc.4-arm64.zip SHA-256 340147a17755431ab7845c818dc925cee84611735b434bfc9aaff8c5a034eab3; service-binaries-mac-arm64.zip SHA-256 58860cd216d1e677f169d2dd2fbb00184836661041716506cd97415c866b3085.
    • The update feed points at this fork. Code signing is ad-hoc only.
  • The cross-process suite in services/tests fails 15 tests on the build machine because a running PAIR application holds ports 11434/1234/14320/14322. The identical failure set reproduces at the base commit, so it is an environment condition, not a regression.
  • No release-candidate profile was recorded for this build. The rc.3 profile in Performance and energy remains the most recent measurement; no percentage improvement is claimed.

Assets

NVPAIR-Setup-0.7.0-rc.4-arm64.dmg and .zip with their blockmaps, service-binaries-mac-arm64.zip (the packaged service binaries), SHA256SUMS, and the macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • The per-job phase durations need a newer oMLX, or a non-streaming request. oMLX 0.7.2's streaming usage chunk carries the token counts but not prompt_eval_duration, generation_duration or time_to_first_token; its non-streaming response does. Against 0.7.2, a streaming job therefore shows its token counts and reads "not reported" for the phase durations — the honest, designed behaviour, not a defect.
  • The live view for a job served on a peer is carried end to end, but it has not been seen reaching a remote member's clients.
  • The engine-native view has not been seen on a node card driven by a live engine.
  • Windows, Linux desktop and Intel Mac runtime; Windows worker-hang recovery and GPU readings.
  • Fresh install on a new machine, uninstall, purge, and corrupt- or interrupted-download handling of this build.
  • Upgrade from rc.3 on a live machine, and the profiling of this build.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.

Personal AI Router 0.7.0 — macOS Apple Silicon

Choose a tag to compare

@JaredP94 JaredP94 released this 22 Oct 12:31

Personal AI Router 0.7.0 — macOS Apple Silicon

The fork's first non-prerelease build. It is the graduated version of the 0.7.0-rc.N line and carries everything those candidates carried. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0-rc.N installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default. The earlier candidates remain on the releases page.

Upgrade notes

  • Desktop 0.7.0 ships service product 2.5.0. The relay envelope protocol stays v2 and no JSON-RPC method was removed, so upgrade desktop/TUI and services together.
  • Mixed clusters: a member running an older workload-manager does not carry the engine-native view from remote nodes, so that view is complete only once every member is upgraded. The originating node is unaffected.
  • Per-node inference totals cover the period since the broker started, and reset when the broker restarts; per-job figures persist with the workload store.

What this release adds

The engine's own view, on the node card

  • Each node's engine reports its own counters — request and token totals, prefill and generation speeds, cache efficiency, loaded models — and PAIR carries them across the cluster and shows them on the node card. They are the engine's numbers, so they include traffic PAIR did not route; they are shown as a separate, labelled "engine self-report" and are never merged with PAIR's own totals.
  • The engine's API key cannot leak: PAIR defines its own response type and reads the engine's payload field by field, so the key the engine returns is dropped by construction.

Live in-flight numbers, on a running job

  • A running job's card shows what is happening now: elapsed time, time to first byte, what has streamed, and — for oMLX — the engine's own token count, decode rate, prefill progress and queue position. Earlier candidates showed nothing until a job ended, so a job stuck in prefill looked identical to one halfway through decoding.
  • No estimates. The live card shows what PAIR measures exactly and what the engine measures exactly. A chunk count is never presented as a token count, and no rate is derived from one. Anything nobody reported reads "not reported", never 0.

What this release fixes

  • A manual peer's engine-native view was never fetched. The engine-native view was read only by the node-scanner, and only for the nodes in its own mDNS directory. A peer registered as a manual node — reached over Tailscale or a static address — is never in that directory, so its record carried its model list but no engine counters, and the desktop showed nothing for it. nvpair-manual-nodes now reads the engine's counters over the same pinned cluster-mTLS client it already used for the model list.
  • A job's live frame rarely carried the engine's numbers. The job's two live publishers shared one per-job frame limiter, and the chunk-driven one won nearly every window, so the engine's half of the frame was almost never published. Both publishers now put both halves on the frame they leave; the one-frame-per-two-seconds bound is unchanged. A pre-existing data race on the frame interval was fixed in the same change.

Full list: CHANGELOG.

Validation

Built from 16e0f87 on a clean tree.

  • make check, npm run dead-code:check and make test pass: 625 desktop unit tests and every Go module, including the new nvpair-shared/inferencemetrics and nvpair-ui-broker/nodemetrics packages. go test -race is green in the broker, the workload-manager and the three inference proxies.
  • The feature was reviewed three times before merge (per task, whole branch, and an independent final pass), and then validated against a live two-node cluster — this machine and a second Mac, paired as cluster members:
    • a request served by the peer carried its measurement and its live frame back to the originating member, under the right job id, with the origin, the engine and the run id travelling with it;
    • the per-job numbers matched the engine's own usage block exactly (prompt tokens 60, completion tokens 199, prefill 320 ms, decode 2470 ms, time to first token 320 ms, total 2790 ms);
    • the peer's engine-native view matched that machine's own oMLX counters exactly (requests 2, prompt tokens 123, completion tokens 599, prefill 161.1 and generation 69.1 tokens per second);
    • with a warm model, 5 of 6 live frames carried the engine's live numbers — the first is published before the engine's rows have been read.
  • Package checks:
    • The app reports 0.7.0, and the service binaries report their services/versions.json versions and are arm64-only.
    • LICENSE, LICENSE.electron.txt, LICENSES.chromium.html and THIRD_PARTY_NOTICES.md are present in the packaged app.
    • The DMG checksum is valid, and the app inside the DMG and the ZIP is identical to the built bundle (content-manifest SHA-256 dc748cd2868551a08744f51fe4ba83608dd92903ccaf641bdd7fa696a8475255).
    • NVPAIR-Setup-0.7.0-arm64.dmg SHA-256 2e43fb5fabd78e1685368f25b6aed85531bd5df5926f2573bc4b4f8cb38f4881; NVPAIR-Setup-0.7.0-arm64.zip SHA-256 5d7eb3c57c6956711994f9849d92749d29262a854d02926fb6491dde26d19189; service-binaries-mac-arm64.zip SHA-256 47d54a1478a7bbb3641c8ead6eadcfbcc6cc3ad588c2aae8abb953985d96cdef.
    • The update feed points at this fork. Code signing is ad-hoc only.
  • The cross-process suite in services/tests fails 15 tests on the build machine because a running PAIR application holds ports 11434/1234/14320/14322. The identical failure set reproduces at the base commit, so it is an environment condition, not a regression.
  • No release-candidate profile was recorded for this build. The rc.3 profile in Performance and energy remains the most recent measurement; no percentage improvement is claimed.

Assets

NVPAIR-Setup-0.7.0-arm64.dmg and .zip with their blockmaps, service-binaries-mac-arm64.zip (the packaged service binaries), SHA256SUMS, and the macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • The per-job phase durations need a newer oMLX, or a non-streaming request. oMLX 0.7.2's streaming usage chunk carries the token counts but not prompt_eval_duration, generation_duration or time_to_first_token; its non-streaming response does. Against 0.7.2 a streaming job shows its token counts and reads "not reported" for the phase durations — the honest, designed behaviour.
  • The first frame of a job carries no engine reading: it is published before the engine's rows have been read.
  • The live card's chunk counter reads 0 for oMLX streams, which carry reasoning_content rather than content deltas; the byte count and the engine's own token count are unaffected.
  • Windows, Linux desktop and Intel Mac runtime; Windows worker-hang recovery and GPU readings.
  • Fresh install on a new machine, uninstall, purge, and corrupt- or interrupted-download handling of this build.
  • Upgrade from a 0.7.0-rc.N build on a live machine, and the profiling of this build.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.

v0.7.0-rc.3 — unsigned macOS arm64 candidate

Choose a tag to compare

@JaredP94 JaredP94 released this 21 Oct 11:27
c4da5fc

Personal AI Router 0.7.0-rc.3 — macOS Apple Silicon candidate

Release candidate for the JaredP94 fork. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0-rc.2 installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default.

Upgrade notes

  • Desktop 0.7.0-rc.3 ships service product 2.3.0. The relay envelope protocol stays v2 and no JSON-RPC method was removed; the new broker methods and the new workload fields are additive, so upgrade desktop/TUI and services together.
  • Mixed clusters: a member running an older workload-manager drops the new measurement from remote jobs, so its per-node totals are complete only once every member is upgraded. The originating node is unaffected. Desktop 0.7.0-rc.2 and services 2.2.0 keep working against each other.
  • Per-node inference totals cover the period since the broker started. The broker's accumulator is in memory, so the per-node figures reset when the broker restarts; per-job figures persist with the workload store.

Changes since 0.7.0-rc.2

Inference metrics

  • Prefill and decode metrics per job and per node. A job card now shows what the request cost: the prefill and decode token counts, how long each phase took, the time to first token, and the decode rate. A node card shows what that node has served — its phase rates over a rolling minute, its mean time to first token and the tokens it served — with a per-model breakdown behind a disclosure.
  • The numbers are the engine's own. PAIR reads the prefill and decode durations that oMLX and Ollama report, and the time to first token and cached-token count that only oMLX reports. Anything an engine does not report is shown as "not reported" rather than as a zero: LM Studio reports no phase split, and Ollama reports no time to first token. No phase is ever estimated.
  • The measurement travels with the workload lifecycle, so a job's figures are visible on every cluster member. Each broker aggregates the jobs it sees per node and per model, and the counts a job once even when the cluster re-delivers its terminal event.
  • The oMLX proxy now asks oMLX for the usage block on streaming requests, so oMLX's own prefill and decode numbers reach the job card instead of being missing.
  • New broker methods metrics:get-node-metrics, metrics:subscribe and metrics:unsubscribe, plus a coalesced metrics:node-metrics push carrying the full per-node snapshot. The desktop re-reads the snapshot every five seconds, because the push is measurement-driven and a node's rate decays as its window empties.

Release housekeeping

  • The macOS installer no longer names a specific candidate version, and the release-profiling harness derives its candidate path from desktop/package.json instead of repeating the version.

Full list: CHANGELOG.

Validation

Built from c4da5fc61d7f437a271e6b0b1e10b1d3d6b3cddc on a clean tree.

  • make check (SPDX headers, build-script verify, lint, typecheck, service contracts, desktop unit tests), npm run dead-code:check, and make test pass on the branch head: 576 desktop unit tests and every Go module, including the new nvpair-shared/inferencemetrics and nvpair-ui-broker/nodemetrics packages. go test -race is green in the broker, the workload-manager and the three inference proxies. The installer's and the profiling harness's own Python suites pass (16 and 59 tests).
  • The cross-process suite in services/tests fails 14 tests on the build machine because a running PAIR application holds ports 11434/1234/14320. The identical failure set reproduces at the merge base, so it is an environment condition, not a regression.
  • The change was reviewed three times before merge: a per-task review for each of the ten implementation tasks, a whole-branch review that returned four findings (all fixed), and a final pre-merge review that returned two more (both fixed).
  • Package checks:
    • The app reports 0.7.0-rc.3, and the 14 service binaries report their services/versions.json versions and are arm64-only.
    • LICENSE, LICENSE.electron.txt, LICENSES.chromium.html and THIRD_PARTY_NOTICES.md are present in the packaged app.
    • The DMG checksum is valid, and the app inside the DMG and the ZIP is identical to the built bundle (content-manifest SHA-256 355167ab29a1ea78fb5dfacbd1e8d1bae07cf6d727e010b260135dd7a4e1c11b).
    • NVPAIR-Setup-0.7.0-rc.3-arm64.dmg SHA-256 de5249c49574a9c67ffd9111a9ea3f1a1728ee0003d5fa82cd32a81d050e6358; NVPAIR-Setup-0.7.0-rc.3-arm64.zip SHA-256 ec5dd48fb0a1b57d66bec85d98864015fd3f61021106a6c8fbe65ad5a55f9b56; service-binaries-mac-arm64.zip SHA-256 448ffc48e0e1cdf3c9398eff5726f7ca66bfb00fd937e2a1b59baa42f5dacc5b.
    • The update feed points at this fork. Code signing is ad-hoc only.
  • No release-candidate profile was recorded for this build. The rc.2 profile in Performance and energy compares rc.2 against rc.1 and remains the most recent measurement; no percentage improvement is claimed for rc.3.

Assets

NVPAIR-Setup-0.7.0-rc.3-arm64.dmg and .zip with their blockmaps, service-binaries-mac-arm64.zip (the packaged service binaries), SHA256SUMS, and the macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • The inference metrics have not been checked against a live engine. The unit tests use a fixture that matches the documented field names, not a running engine. Before relying on them: confirm that a live oMLX emits the usage block (with prompt_eval_duration, generation_duration, time_to_first_token and total_time) once the proxy sends stream_options.include_usage, and that the values match /admin/api/stats deltas; confirm that Ollama's nanosecond durations convert correctly; and confirm whether LM Studio's streaming responses carry a usage block at all. If it does not, LM Studio jobs show token counts on the native route and nothing on the OpenAI-compatible one.
  • A two-node cluster run — a request served by node B showing the measurement and the per-node total on both members — has not been performed against a live cluster, nor has the mixed-version case been exercised.
  • Windows, Linux desktop and Intel Mac runtime; Windows worker-hang recovery and GPU readings.
  • Fresh install on a new machine, uninstall, purge, and corrupt- or interrupted-download handling of this build.
  • Upgrade from rc.2 on a live machine, and the profiling of this build.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.

v0.7.0-rc.2 — unsigned macOS arm64 candidate

Choose a tag to compare

@JaredP94 JaredP94 released this 20 Oct 18:42
99051fc

Personal AI Router 0.7.0-rc.2 — macOS Apple Silicon candidate

Release candidate for the JaredP94 fork. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. It targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included. Privileged-helper registration and automatic firewall setup stay unavailable in unsigned builds: instead of prompting, PAIR shows Firewall setup: manual guidance under Settings → Service.

It is the fork's Latest release, so 0.7.0-rc.1 installs are offered it through the in-app updater, and scripts/install-mac.sh installs it by default.

Upgrade notes

  • Desktop 0.7.0-rc.2 ships service product 2.2.0. The relay envelope protocol stays v2, but some JSON-RPC methods were removed (six legacy telemetry settings methods, telemetry/check-update and telemetry/update), so upgrade desktop/TUI and services together.
  • Settings migrate to schema 2. Tracing and content capture are turned off and must be re-enabled in Settings → Service; content capture requires explicit consent. Proxies no longer read PAIR_TELEMETRY_* / OTEL_* environment variables.
  • Mixed clusters: an rc.1 node polls node-info without the new sampling header, which keeps upgraded nodes sampling their GPU every 2 seconds. Idle backoff applies once every node is upgraded.

Changes since 0.7.0-rc.1

Reliability

  • Worker health: every worker answers a health check. The broker checks every 30 s, marks a worker degraded after 2 missed checks, and restarts eight workers that run no child processes after 3. Engine manager and the three proxies are never restarted automatically on a hang (crash recovery still applies); they show as "Not responding — restart manually". Optional workers whose first launch fails are retried, and missing binaries are reported as missing. Settings → Service and the terminal interface Overview show every worker's state, with Restart.
  • A worker that stops reading its input no longer blocks the broker or the restart that would recover it.

Engines

  • nvpair engine <engine> [args…] runs an installed engine's own command line without changing PATH.
  • Engine manager reports what each engine supports (model list, download, delete, port change, install, uninstall); the desktop and terminal interface offer only those actions.
  • oMLX counts as installed only when the command line PAIR runs exists (~/.omlx/bin/omlx, /opt/homebrew/bin/omlx or /usr/local/bin/omlx), so starting it no longer fails with "no such file or directory". Uninstall is offered only when it would remove that installation.
  • Changing an engine's port keeps the rest of a custom engine override. A model download the engine rejects is reported as a failure.

Terminal interface

  • Lists, downloads and deletes models, changes a local engine's port, updates an engine, starts, stops and installs engines on cluster peers, shows which node ran each workload, and confirms every destructive action.

GPU readings

  • Each GPU reports its memory as dedicated, unified, shared or unavailable. Unknown readings show as "—" instead of 0, and charts leave gaps. Windows reports shared memory separately; Intel integrated GPUs on Macs are reported as shared. Linux AMD/Intel GPUs remain "Memory unavailable" (no new driver support).

Tracing and privacy

  • Tracing is per node, local-only and off by default, with explicit consent for content capture, a loopback-only managed Phoenix pinned by digest, on-device trace storage size, and a confirmed Clear stored traces action. Serving nodes record nothing for peer-originated requests.

Idle work and protocol

  • GPU sampling relaxes to 10 s when nothing needs fresh data, including tray-only sessions, while keeping the scheduler's 10 s freshness budget.
  • The desktop validates relay envelopes the same way as the Go services, against a shared test corpus.

Packaging

  • The app ships Chromium's LICENSES.chromium.html and Electron's license, and packaging fails if they are missing.

Full list: CHANGELOG.

Validation

Built from 99051fc3bf068f79e31e07f0ae32f619526a6e88 on a clean tree.

  • On 8e5713e (before the last fixes): make check, dead-code, make licenses-check, installer tests, and go test -race in every Go module passed. Skipped: four engine-manager process-ownership tests (this Mac cannot resolve which process owns a port) and one test needing a live oMLX engine.
  • Later fixes (#10–#15) each passed make check, dead-code and the race suites of the modules they changed; make check and dead-code passed again before the release build.
  • Package checks:
    • The app reports 0.7.0-rc.2, and all 14 service binaries report their services/versions.json versions and are arm64-only.
    • LICENSE, THIRD_PARTY_NOTICES.md and the Electron/Chromium license files are byte-identical to their sources.
    • The DMG checksum is valid, and the app inside the DMG and the ZIP is identical to the built bundle.
    • The update feed points at this fork.
    • Code signing is ad-hoc only.
  • Same-artifact evidence: no source file changed between the upgrade-tested and profiled build (86214bd) and this one (only docs). The bundles differ only in 16 Go binaries (14 services, collectlogs, inference-dispatcher), which embed the source commit and build time, and the two manifests recording build metadata; the services source fingerprint (73c1e004…) is unchanged.
  • Upgrade: a backed-up macOS arm64 machine in a live three-node cluster was upgraded from rc.1 to the 86214bd build with scripts/install-mac.sh --dmg. It kept its node ID and cluster membership, migrated settings (tracing off), started all 12 workers, and its oMLX engine started. It was then restored to rc.1.
  • Profiling: about 30 sandboxed launches of rc.2 and of rc.1 (with only its privileged-helper control tool removed so it skips its first-launch dialog) each quit cleanly with no leftover processes. Tray-only and Overview profiles show CPU and memory in line with rc.1; package idle wakeups rose from about 0.4 to 2.3 per second (cause not established). See Performance and energy. No percentage improvement is claimed.

Assets

NVPAIR-Setup-0.7.0-rc.2-arm64.dmg and .zip with their blockmaps, service-binaries-mac-arm64.zip (the packaged service binaries), SHA256SUMS, and the macOS update feeds latest-mac.yml / latest-arm64-mac.yml.

Not validated

  • Windows, Linux desktop and Intel Mac runtime; Windows worker-hang recovery, GPU readings and nvpair engine console behaviour.
  • Inference through the packaged candidate, tracing-enabled profiling, and profiling of a clustered node with engines.
  • Fresh install on a new machine, uninstall, purge, and corrupt- or interrupted-download handling of this build.
  • Apple trust: no Developer ID signing or notarization; Gatekeeper may block first launch.
  • macOS may stop answering LAN connections after a long time unclustered (known issue; restart PAIR).

v0.7.0-rc.1 — unsigned macOS arm64 candidate

Choose a tag to compare

@JaredP94 JaredP94 released this 17 Oct 12:08

Personal AI Router 0.7.0-rc.1 — macOS Apple Silicon candidate

Release candidate for the JaredP94 fork. Unsigned and not notarized. Not a production-ready or NVIDIA-signed distribution. The privileged helper is unavailable in this unsigned build. This candidate targets macOS arm64 only; Windows, Linux desktop and Intel Mac packages are not included.

Upgrade compatibility

This release adopts relay protocol v2. Upgrade the desktop/TUI and bundled service binaries together; do not mix workers or clients from older protocol versions. Notifications carry protocol/epoch/sequence metadata, while requests and responses remain unstamped. Incompatible stdio sessions now terminate instead of continuing with an unsupported contract.

Desktop release versions and service versions are independent. This candidate uses desktop 0.7.0-rc.1, service product/installer 1.1.0, TUI 1.1.0, node-settings/cluster-manager 2.0.1, and the other service components 1.0.1. Existing protocol-v2 major bumps are retained, not repeated.

Changes since 0.6.0

  • State recovery: The broker announces its protocol epoch and provides authoritative resync snapshots. Desktop and TUI refresh recovered state per domain after an epoch change, without sequence-gap polling or repeated healthy-connection resync bursts.
  • Liveness and reconnect ownership: Inbound-silence detection expires unresponsive sessions. Recovery stays with the owning frontend, uses a bounded readiness deadline, and reports a failed automatic restart rather than hiding it. Desktop retains shutdown ownership across a silence reconnect.
  • TUI recovery: Successful snapshot domains still apply when optional workers are unavailable. Workload snapshots use the broker's object-shaped result; optional failures remain silent rather than causing repeated recovery notices. Failed connection setup does not stop notification consumption.
  • Shutdown and failed starts: Client writes are cancellation-aware where shutdown requires it. Heartbeat shutdown joins are bounded. A failed desktop startup reaps the subprocess instances it created without disturbing a newer start attempt.
  • Service-authoritative metrics: Routing metric calculations live in the Go proxies rather than being reimplemented in clients. The broker reuses one codec per node-info connection.
  • Regression coverage: TCP backpressure fixtures are constrained rather than relying on platform socket-buffer defaults; heartbeat fixture cleanup joins work before restoring the global logger; the malformed-connection fixture no longer races on a shared timeout.

Candidate validation

Verified candidate commit: d18e6d25cac0d13322a791c03f592bb06d4e61f6 (release/v0.7.0-rc.1). Independent metadata/notes/plan review reported no findings; runtime and artifact approval remained separate verification obligations.

  • Fresh desktop checks passed: SPDX/build-script checks, lint, split-target typechecking, service contracts, dead-code check, 328 unit tests and 656 modular test executions across the configured projects.
  • Fresh isolated Linux checks passed: all 16 ordinary Go modules (1,705 test/subtest passes), six full race suites (927 passes), and cross-process integration (90 passes). The named live-oMLX test was skipped once in ordinary and once in race execution; earlier live smoke evidence below is separate, not a pass for these newly versioned packages. Counts include Go subtests and are not counts of unique scenarios.
  • Native macOS arm64 bundle and unsigned DMG/ZIP builds passed. DMG verification and both application/service ZIP integrity checks passed. Packaged application plist/ASAR versions, all 14 service versions, exact service inventory, executable modes, arm64 architectures, sizes and SHA-256 hashes were verified. The source fingerprint was independently reproduced; application ZIP contents matched the inspected bundle. Dispatcher/log-collector payloads and universal arm64/x86_64 helper architectures were checked; packaged helper runtime limits are disclosed below.
  • Code-signing inspection found ad-hoc linker signatures, not Apple Developer ID signing or notarization. The application lacks a complete sealed-resource signature; normal privileged-helper registration failed with signing error -67056. The unchanged helper trust policy additionally requires the official NVIDIA publisher, so an arbitrary fork signing certificate would not make this helper flow valid. No trust bypass or signature modification was used.
  • The exact packaged candidate was temporarily installed and launched normally on a backed-up macOS arm64 test machine. Node-info and packaged proxy model inventory became ready; an independent rerun reproduced transient model-inventory 503 responses followed by 200 with six models when readiness was properly awaited. Three separate bounded two-turn SSE smokes through the packaged oMLX proxy completed with HTTP200, nonempty output and [DONE], using existing Qwen3.5-0.8B weights without downloads. No prompts, responses or credentials were logged. This does not certify renderer interaction, cache hits, GPU placement or multi-host behavior.
  • Ordinary-user non-purge uninstall removed the unlaunched candidate in a separate trial and retained current/legacy application data byte-identically. A fresh backed-up lifecycle run passed normal launch, bounded model readiness, two SSE turns, canonical exit with no remaining app-owned processes, normal relaunch with all 12 supervised workers, another two SSE turns, and a second canonical exit with no remaining app-owned processes. No forced termination or dialog/security-consent automation was used.
  • After that run, the original 0.6.0 app and all nine configured app-data/framework/launcher snapshots were restored and verified before normal relaunch, with preference logical equality and node-info200 afterward. Original helper status, global firewall settings, the immediate pre-run firewall listing and oMLX settings hash were unchanged. This does not claim restoration of older historical firewall-list entries or the complete original engine runtime. Privileged uninstall cleanup and purge behavior remain uncertified.
  • Six artifact assets are included unchanged: application DMG/ZIP, their blockmaps, the service ZIP built from the verified packaged payload, and SHA256SUMS. The generated latest-mac.yml, previously excluded from the prerelease, is now included with an identical latest-arm64-mac.yml alias for macOS update discovery. Both metadata files match the exact candidate ZIP/DMG sizes and SHA-512 hashes; no prerelease-channel metadata was generated. At the user's request, this candidate is now the fork's regular/latest GitHub release and includes macOS updater metadata. The prior v0.6.0 release assets and feed files are unchanged.

Verification-harness disclosure: an initial artifact-check script stopped on an incorrect guessed log-collector filename. The actual packaged collectlogs matched the canonical build script; only the ignored checker was corrected, its failed evidence was retained, and corrected verification passed without changing/rebuilding candidate source or artifacts.

Important limitations

  • No Apple Developer ID signing or notarization is provided. Standard Apple trust assessment failed; this release does not assert normal trusted installation or automatic-updater compatibility.
  • Privileged helper registration and automatic helper-based firewall setup do not work in the tested unsigned package. Normal macOS network permission prompts may still occur as needed. First-run helper explanation dialogs may repeat while setup remains incomplete; do not bypass OS security to make them succeed.
  • An earlier shutdown was blocked by an unidentified native alert until user dismissal. Its exact identity was not established; source inspection makes the first-run helper explanation a hypothesis, not a confirmed diagnosis. The later full bounded lifecycle run passed both normal exits and relaunch without forced termination or UI automation. This does not guarantee that permission/setup dialogs will never recur or constitute production-ready certification.
  • Genuine multi-host behavior, native Windows/Linux desktop and Intel Mac runtime validation remain outstanding.
  • The earlier five-turn live oMLX endpoint smoke passed using an existing advertised Qwen3.5-0.8B model and showed affinity telemetry on follow-ups. It does not establish KV-cache hits or a speedup. The existing oMLX distributed surface was enabled, so strictly local-only GPU execution was not established. The engine was stopped afterward and its settings were unchanged.
  • Prior checks and service cross-builds do not certify every engine/GPU/platform combination. Later authorized packaged-runtime checks supplement, rather than replace, the earlier isolated suites. No new engine installation/download commands, source changes or artifact rebuilds were used to obtain those runtime results.

The user explicitly requested regular/latest release status for in-app update discovery. This changes GitHub release/channel metadata only: version 0.7.0-rc.1 remains a release candidate, unsigned and unnotarized, with the helper and lifecycle limitations above. It is not a new signed or production-certified build; automatic installation through macOS trust/signature checks has not been certified.

Personal AI Router 0.6.0

Choose a tag to compare

@JaredP94 JaredP94 released this 04 Oct 16:52

Highlights in v0.6.0

Menu Bar Job Activity

• Live Job Count in the Icon: The tray icon now reports queued, initializing, and running jobs as a numeral inside the PAIR pentagon, capped at 9+, replacing the static mark.
• Failure Alert: A ! marks a failed job for 30 seconds and then clears, so a retired failure cannot shout forever. Windows and Linux render it in red; macOS paints a template image in the menu bar's own colour, so there the glyph shape carries the alert.
• No More White Square: The icon shipped as a macOS template image built from the full-colour app icon. Template rendering keeps only the alpha channel, and the mark's node glyph is dark paint rather than transparency, so it flattened to a solid block. The mark is now drawn from pixel maps with genuine cutouts, so template mode has something to draw.
• Hover Detail: The tooltip spells out the counts (PAIR — 2 active · 1 failed) instead of the application name alone.
• No Repaint Storm: The icon redraws when it would look different rather than on every event, because a backend restart evicts one workload catalog entry at a time.

Personal AI Router 0.5.0

Choose a tag to compare

@JaredP94 JaredP94 released this 02 Oct 12:12

Highlights in v0.5.0

Observability & Telemetry Updates

• Phoenix Docker Image Update Checks: Added in-app and background image freshness checks against Docker Hub Registry API (arizephoenix/phoenix:latest) comparing container and remote image digests via telemetry/check-update.
• In-App Phoenix Container Updates: Enabled triggering Phoenix Docker image pulls and non-blocking container rebuild/restart directly from PAIR UI via telemetry/update.
• Observability UI Enhancements: Added Phoenix image version badges (v20.19.0), an update alert banner with version target and dismiss support, a manual "Check for Updates" button, and an "Update Phoenix" action button to ObservabilityCard in Service Settings.
• Dynamic Compose Project Detection: Enhanced scripts/telemetry-phoenix.sh with update and pull subcommands and automatic -p "$EXISTING_PROJECT" detection, eliminating naming and container recreation collisions across packaged and dev environments.

Personal AI Router 0.4.1

Choose a tag to compare

@JaredP94 JaredP94 released this 28 Sep 12:32

Highlights in v0.4.1

Bug Fixes & Reliability

• Packaged App Phoenix Telemetry Compose Resolution: Added docker-compose.telemetry.yml and scripts/telemetry-phoenix.sh to packaged application resources (extraResources) and passed --telemetry-compose-path to the supervisor broker to ensure seamless Docker startup in production builds.
• Automatic Fallback Compose Provisioning: Enabled nvpair-ui-broker to automatically self-provision the default Phoenix Docker Compose YAML into the user configuration directory if missing.
• Asynchronous Docker Pulls & Condition Polling: Handed off long Docker Compose operations (such as initial image pulls) to a background worker in nvpair-ui-broker with an extended 10-minute timeout and transitional "starting" container state, preventing JSON-RPC timeout errors.
• Collector Endpoint Condition Polling: Implemented active condition-based TCP polling of the OpenTelemetry collector port (:4317) before registering the service.
• Observability UI Responsiveness: Accelerated UI polling to 1.5s during container startup, added a yellow "Starting…" status badge, and safely disabled dashboard links until the collector port responds.