@trillboards/edge-sdk 0.2.53 → 0.2.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/macos/README.md +4 -4
- package/deploy/macos/bench-local-vlm.sh +140 -0
- package/deploy/macos/build-macos-pkg.sh +3 -2
- package/deploy/windows/README.md +7 -5
- package/deploy/windows/bundle-windows-installer.ps1 +1 -3
- package/deploy/windows/e2e/test-local-sense.ps1 +97 -6
- package/dist/AudienceAnalyzeClient.d.ts +12 -1
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -1
- package/dist/AudienceAnalyzeClient.js +1 -0
- package/dist/AudienceAnalyzeClient.js.map +1 -1
- package/dist/ChannelProber.d.ts +22 -0
- package/dist/ChannelProber.d.ts.map +1 -1
- package/dist/ChannelProber.js +47 -3
- package/dist/ChannelProber.js.map +1 -1
- package/dist/CloudSensingManager.d.ts.map +1 -1
- package/dist/CloudSensingManager.js +8 -1
- package/dist/CloudSensingManager.js.map +1 -1
- package/dist/EdgeAgent.js +1 -1
- package/dist/OnvifClient.d.ts +135 -3
- package/dist/OnvifClient.d.ts.map +1 -1
- package/dist/OnvifClient.js +303 -11
- package/dist/OnvifClient.js.map +1 -1
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.js +1 -1
- package/dist/localVlmBench.d.ts +102 -0
- package/dist/localVlmBench.d.ts.map +1 -1
- package/dist/localVlmBench.js +129 -0
- package/dist/localVlmBench.js.map +1 -1
- package/dist/sensingCatchRate.d.ts +83 -0
- package/dist/sensingCatchRate.d.ts.map +1 -1
- package/dist/sensingCatchRate.js +63 -2
- package/dist/sensingCatchRate.js.map +1 -1
- package/package.json +1 -1
package/deploy/macos/README.md
CHANGED
|
@@ -40,7 +40,7 @@ delivered **only by pairing** — it is never baked into the `.pkg`.
|
|
|
40
40
|
|
|
41
41
|
## Install (operator)
|
|
42
42
|
|
|
43
|
-
1. Download `
|
|
43
|
+
1. Download `SenseAnythingConnector.pkg`.
|
|
44
44
|
2. Double-click it. The installer offers **Install for me only** (home-domain) —
|
|
45
45
|
no admin password. (Equivalent CLI: `installer -pkg <pkg> -target
|
|
46
46
|
CurrentUserHomeDirectory`.)
|
|
@@ -75,7 +75,7 @@ launchctl kickstart -k "gui/$(id -u)/com.trillboards.edge"
|
|
|
75
75
|
cd trillboards-edge-sdk
|
|
76
76
|
npm install # ensures ffmpeg-static is fetched
|
|
77
77
|
cd packages/edge-sdk/deploy/macos
|
|
78
|
-
./build-macos-pkg.sh # → dist-installer/
|
|
78
|
+
./build-macos-pkg.sh # → dist-installer/SenseAnythingConnector.pkg
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
Options:
|
|
@@ -136,9 +136,9 @@ To ship a Gatekeeper-clean installer, on a machine that has the
|
|
|
136
136
|
# (or: export MAC_INSTALLER_IDENTITY="Developer ID Installer: …" && ./build-macos-pkg.sh)
|
|
137
137
|
|
|
138
138
|
# 2. Notarize + staple
|
|
139
|
-
xcrun notarytool submit dist-installer/
|
|
139
|
+
xcrun notarytool submit dist-installer/SenseAnythingConnector.pkg \
|
|
140
140
|
--keychain-profile <notary-profile> --wait
|
|
141
|
-
xcrun stapler staple dist-installer/
|
|
141
|
+
xcrun stapler staple dist-installer/SenseAnythingConnector.pkg
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
The bundled `bin/node` and `bin/ffmpeg` are third-party Mach-O binaries; for full
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# bench-local-vlm.sh — macOS twin of `deploy/windows/e2e/test-local-sense.ps1
|
|
4
|
+
# -Mode bench`: provision the PINNED litert-lm + Gemma 4 E2B, start a real
|
|
5
|
+
# serve, and MEASURE this machine's per-frame cost.
|
|
6
|
+
#
|
|
7
|
+
# WHY IT EXISTS. Local-only inference makes the box spec the product spec, and
|
|
8
|
+
# every latency number in the capacity plan came off one Apple M4 Max
|
|
9
|
+
# workstation — including the 7.30 s/frame in connectorCadence.ts that sizes the
|
|
10
|
+
# whole 493-analyses/hour budget. A 3-core / 7 GB Apple silicon runner is the
|
|
11
|
+
# closest CI has to the Mac mini we would actually recommend, and it is the only
|
|
12
|
+
# cheap way to test the "16 GB+ RAM" minimum the activation runbook publishes.
|
|
13
|
+
#
|
|
14
|
+
# It does NOT use setup-litertlm.sh's LaunchAgent path: that bootstraps a
|
|
15
|
+
# per-login agent, and a CI runner's session is not the session a customer logs
|
|
16
|
+
# into. The runtime, the pin and the model are identical; only the supervisor
|
|
17
|
+
# differs, and the supervisor is not what is being measured.
|
|
18
|
+
#
|
|
19
|
+
# NOTE ON BASH 3.2. macOS still ships bash 3.2 as /bin/bash and that is what a
|
|
20
|
+
# GitHub macOS runner executes. Its identifier scan is NOT UTF-8 aware, so an
|
|
21
|
+
# expansion written `$VAR…` swallows the ellipsis bytes into the variable NAME
|
|
22
|
+
# and `set -u` then reports an unbound variable whose name is the real one with
|
|
23
|
+
# mojibake stapled to it — which reads as "the variable is unset" when it is set.
|
|
24
|
+
# Every expansion here is braced and every log line is ASCII for that reason.
|
|
25
|
+
#
|
|
26
|
+
# Usage:
|
|
27
|
+
# deploy/macos/bench-local-vlm.sh [--port 9379] [--arms a,b] [--frames f]
|
|
28
|
+
# [--rounds 1] [--budget-min 40]
|
|
29
|
+
# [--frame-timeout-min 20] [--out FILE]
|
|
30
|
+
# [--model <non-default>.litertlm]
|
|
31
|
+
#
|
|
32
|
+
# Exit 0 = a matrix was written (even a partial one — a slow box is a RESULT).
|
|
33
|
+
# Exit 1 = nothing was measured at all.
|
|
34
|
+
set -uo pipefail
|
|
35
|
+
|
|
36
|
+
PORT=9379
|
|
37
|
+
ARMS='cpu-sop,cpu-dooh-sop,gpu-sop'
|
|
38
|
+
FRAMES='kitchen-5-people'
|
|
39
|
+
ROUNDS=1
|
|
40
|
+
BUDGET_MIN=40
|
|
41
|
+
FRAME_TIMEOUT_MIN=20
|
|
42
|
+
OUT="${TMPDIR:-/tmp}/bench-local-vlm.json"
|
|
43
|
+
NOTE=''
|
|
44
|
+
# A NON-default .litertlm id, for the per-silicon A/B. Empty = the generic file
|
|
45
|
+
# both provisioners import everywhere.
|
|
46
|
+
MODEL=''
|
|
47
|
+
|
|
48
|
+
while [ $# -gt 0 ]; do
|
|
49
|
+
case "$1" in
|
|
50
|
+
--port) PORT="$2"; shift 2 ;;
|
|
51
|
+
--arms) ARMS="$2"; shift 2 ;;
|
|
52
|
+
--frames) FRAMES="$2"; shift 2 ;;
|
|
53
|
+
--rounds) ROUNDS="$2"; shift 2 ;;
|
|
54
|
+
--budget-min) BUDGET_MIN="$2"; shift 2 ;;
|
|
55
|
+
--frame-timeout-min) FRAME_TIMEOUT_MIN="$2"; shift 2 ;;
|
|
56
|
+
--out) OUT="$2"; shift 2 ;;
|
|
57
|
+
--note) NOTE="$2"; shift 2 ;;
|
|
58
|
+
--model) MODEL="$2"; shift 2 ;;
|
|
59
|
+
*) echo "unknown flag: $1" >&2; exit 2 ;;
|
|
60
|
+
esac
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # <edge-sdk>/deploy/macos
|
|
64
|
+
PKG_ROOT="$(cd "$HERE/../.." && pwd)" # <edge-sdk>
|
|
65
|
+
WORKSPACE_ROOT="$(cd "$PKG_ROOT/../.." && pwd)" # <repo>/trillboards-edge-sdk
|
|
66
|
+
[ -f "$PKG_ROOT/scripts/bench-local-vlm.mjs" ] || { echo "FAIL - PKG_ROOT wrong: $PKG_ROOT" >&2; exit 1; }
|
|
67
|
+
[ -f "$WORKSPACE_ROOT/package.json" ] || { echo "FAIL - WORKSPACE_ROOT wrong: $WORKSPACE_ROOT" >&2; exit 1; }
|
|
68
|
+
log() { echo "[macos-bench] $*"; }
|
|
69
|
+
die() { echo "FAIL - $*" >&2; exit 1; }
|
|
70
|
+
|
|
71
|
+
# The PINNED version, read from the provisioner rather than restated here — the
|
|
72
|
+
# litert-lm-version-pin guard already keeps that one declaration honest, and a
|
|
73
|
+
# second copy would be a second thing to forget.
|
|
74
|
+
LITERT_LM_VERSION="$(sed -n 's/^LITERT_LM_VERSION="\${LITERT_LM_VERSION:-\([^}]*\)}"/\1/p' "$HERE/scripts/setup-litertlm.sh" | head -1)"
|
|
75
|
+
[ -n "$LITERT_LM_VERSION" ] || die "could not read the pinned litert-lm version from setup-litertlm.sh"
|
|
76
|
+
log "pinned litert-lm: $LITERT_LM_VERSION"
|
|
77
|
+
|
|
78
|
+
log "building the connector (tsc, all workspaces in dependency order) ..."
|
|
79
|
+
( cd "$WORKSPACE_ROOT" && npm run build ) || die "npm run build failed"
|
|
80
|
+
|
|
81
|
+
if ! command -v uv >/dev/null 2>&1; then
|
|
82
|
+
log "installing uv (home-domain, no sudo) ..."
|
|
83
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh || die "uv install failed"
|
|
84
|
+
fi
|
|
85
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
86
|
+
|
|
87
|
+
log "installing litert-lm==${LITERT_LM_VERSION} ..."
|
|
88
|
+
uv tool install --python 3.12 --managed-python --force "litert-lm==$LITERT_LM_VERSION" \
|
|
89
|
+
|| die "litert-lm install failed"
|
|
90
|
+
LITERTLM="$HOME/.local/bin/litert-lm"
|
|
91
|
+
[ -x "$LITERTLM" ] || die "litert-lm not installed at $LITERTLM"
|
|
92
|
+
|
|
93
|
+
MODEL_ID='gemma-4-E2B-it.litertlm'
|
|
94
|
+
HF_REPO='litert-community/gemma-4-E2B-it-litert-lm'
|
|
95
|
+
if ! "$LITERTLM" list 2>/dev/null | grep -q "$MODEL_ID"; then
|
|
96
|
+
# EXACT form setup-litertlm.sh uses. The positional argument is the FILE inside
|
|
97
|
+
# the repo, not the repo: passing the repo id alone gets
|
|
98
|
+
# "Source file not found: <repo>", because the bare form imports a LOCAL path.
|
|
99
|
+
log "importing ${MODEL_ID} from ${HF_REPO} (~2.4 GB) ..."
|
|
100
|
+
"$LITERTLM" import --from-huggingface-repo "$HF_REPO" "$MODEL_ID" || die "model import failed"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
SERVE_LOG="${TMPDIR:-/tmp}/litertlm-serve-bench.log"
|
|
104
|
+
if curl -fsS --max-time 3 "http://127.0.0.1:$PORT/v1/models" >/dev/null 2>&1; then
|
|
105
|
+
log "a serve is already healthy on :$PORT"
|
|
106
|
+
SERVE_PID=''
|
|
107
|
+
else
|
|
108
|
+
log "starting litert-lm serve on 127.0.0.1:$PORT (log: $SERVE_LOG)"
|
|
109
|
+
"$LITERTLM" serve --host 127.0.0.1 --port "$PORT" --verbose > "$SERVE_LOG" 2>&1 &
|
|
110
|
+
SERVE_PID=$!
|
|
111
|
+
fi
|
|
112
|
+
cleanup() { [ -n "${SERVE_PID:-}" ] && kill "$SERVE_PID" 2>/dev/null; }
|
|
113
|
+
trap cleanup EXIT
|
|
114
|
+
|
|
115
|
+
HEALTHY=0
|
|
116
|
+
for _ in $(seq 1 120); do
|
|
117
|
+
if curl -fsS --max-time 3 "http://127.0.0.1:$PORT/v1/models" >/dev/null 2>&1; then HEALTHY=1; break; fi
|
|
118
|
+
[ -n "${SERVE_PID:-}" ] && ! kill -0 "$SERVE_PID" 2>/dev/null && break
|
|
119
|
+
sleep 5
|
|
120
|
+
done
|
|
121
|
+
[ "$HEALTHY" = "1" ] || { tail -40 "$SERVE_LOG" 2>/dev/null; die "litert-lm serve never became healthy on :$PORT"; }
|
|
122
|
+
log "litert-lm serve healthy on :$PORT"
|
|
123
|
+
|
|
124
|
+
log "running the hardware matrix — arms=$ARMS frames=$FRAMES rounds=$ROUNDS budget=${BUDGET_MIN}m"
|
|
125
|
+
node "$PKG_ROOT/scripts/bench-local-vlm.mjs" \
|
|
126
|
+
--litert "http://127.0.0.1:$PORT" \
|
|
127
|
+
--arms "$ARMS" --frames "$FRAMES" --rounds "$ROUNDS" \
|
|
128
|
+
--budget-ms "$((BUDGET_MIN * 60000))" \
|
|
129
|
+
--timeout-ms "$((FRAME_TIMEOUT_MIN * 60000))" \
|
|
130
|
+
--machine-note "$NOTE" \
|
|
131
|
+
${MODEL:+--model "$MODEL"} \
|
|
132
|
+
--out "$OUT"
|
|
133
|
+
BENCH_EXIT=$?
|
|
134
|
+
|
|
135
|
+
# A bench REPORTS; it does not gate. Exiting non-zero because a machine is slow
|
|
136
|
+
# would turn "this box is too slow" into "the lane is broken" — the confusion
|
|
137
|
+
# that left windows-latest unmeasured for two months. Only producing NOTHING fails.
|
|
138
|
+
[ -f "$OUT" ] || die "bench produced no matrix at all (node exit $BENCH_EXIT)"
|
|
139
|
+
log "matrix written: $OUT"
|
|
140
|
+
exit 0
|
|
@@ -104,6 +104,7 @@ WORKSPACE_ROOT="$(cd "$PKG_ROOT/../.." && pwd)" # …/trillboards-edge-sdk
|
|
|
104
104
|
|
|
105
105
|
BUNDLE_ID="com.trillboards.edge"
|
|
106
106
|
APP_NAME="TrillboardsEdge"
|
|
107
|
+
INSTALLER_NAME="SenseAnythingConnector"
|
|
107
108
|
INSTALL_SUBDIR="Library/Trillboards/edge" # relative to the user home
|
|
108
109
|
|
|
109
110
|
# ─── Args ────────────────────────────────────────────────────────────────────
|
|
@@ -176,7 +177,7 @@ DIST_DIR="$PKG_ROOT/deploy/macos/dist-installer"
|
|
|
176
177
|
STAGE="$DIST_DIR/stage-$ARCH_LABEL" # the payload root (== the user home view)
|
|
177
178
|
PAYLOAD="$STAGE/$INSTALL_SUBDIR" # …/Library/Trillboards/edge
|
|
178
179
|
SCRATCH="$DIST_DIR/scratch-$ARCH_LABEL"
|
|
179
|
-
PKG_OUT="$DIST_DIR/${
|
|
180
|
+
PKG_OUT="$DIST_DIR/${INSTALLER_NAME}.pkg"
|
|
180
181
|
COMPONENT_PKG="$SCRATCH/${APP_NAME}-component.pkg"
|
|
181
182
|
SETUP_APP="$STAGE/Applications/Trillboards CCTV Setup.app"
|
|
182
183
|
|
|
@@ -590,7 +591,7 @@ productbuild \
|
|
|
590
591
|
# ─── 10. Optional sign ───────────────────────────────────────────────────────
|
|
591
592
|
if [ -n "$SIGN_IDENTITY" ]; then
|
|
592
593
|
log "productsign with '$SIGN_IDENTITY'…"
|
|
593
|
-
SIGNED="$DIST_DIR/${
|
|
594
|
+
SIGNED="$DIST_DIR/${INSTALLER_NAME}-signed.pkg"
|
|
594
595
|
productsign --sign "$SIGN_IDENTITY" "$PKG_OUT" "$SIGNED"
|
|
595
596
|
mv "$SIGNED" "$PKG_OUT"
|
|
596
597
|
log "Signed: $PKG_OUT"
|
package/deploy/windows/README.md
CHANGED
|
@@ -70,15 +70,17 @@ serves every Windows 10/11 — no per-arch builds.
|
|
|
70
70
|
./build-windows.ps1 -Offline # copy host node/ffmpeg (air-gapped)
|
|
71
71
|
|
|
72
72
|
# after the inner installer is signed, create the one-file customer artifact
|
|
73
|
-
./bundle-windows-installer.ps1 -InnerInstaller <signed-inner.exe>
|
|
73
|
+
./bundle-windows-installer.ps1 -InnerInstaller <signed-inner.exe> # -> dist-installer\customer\SenseAnythingConnector.exe
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Requires NSIS and 7-Zip on PATH (`choco install nsis 7zip -y`). The release workflow publishes
|
|
77
|
-
the `.exe` to `s3://trillboards-screen-static/connector/
|
|
77
|
+
the `.exe` to `s3://trillboards-screen-static/connector/SenseAnythingConnector.exe`
|
|
78
78
|
plus `trillboards-connector-windows.version.json`, containing the exact connector
|
|
79
|
-
version, production commit, SHA-256, file size, and publication time.
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
version, production commit, SHA-256, file size, and publication time. The old
|
|
80
|
+
`trillboards-connector-windows.exe` object remains a compatibility alias, with a
|
|
81
|
+
content-disposition header that still downloads as `SenseAnythingConnector.exe`.
|
|
82
|
+
It then invalidates the `screen.trillboards.com` CloudFront distribution, so the
|
|
83
|
+
portal's stable download URL never changes while field tests remain artifact-verifiable.
|
|
82
84
|
|
|
83
85
|
## Notes
|
|
84
86
|
|
|
@@ -37,9 +37,7 @@ if (-not (Test-Path -LiteralPath $InnerInstaller -PathType Leaf)) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if ([string]::IsNullOrWhiteSpace($OutputPath)) {
|
|
40
|
-
$
|
|
41
|
-
if ([string]::IsNullOrWhiteSpace($version)) { $version = "unknown" }
|
|
42
|
-
$OutputPath = Join-Path (Join-Path $DistDir "customer") "TrillboardsEdgeSetup-$version-x64.exe"
|
|
40
|
+
$OutputPath = Join-Path (Join-Path $DistDir "customer") "SenseAnythingConnector.exe"
|
|
43
41
|
}
|
|
44
42
|
$OutputPath = [System.IO.Path]::GetFullPath($OutputPath)
|
|
45
43
|
|
|
@@ -18,6 +18,18 @@
|
|
|
18
18
|
connector → serve → preAnalyzed → assert plumbing WITHOUT the ~2.4 GB model.
|
|
19
19
|
This is a STUB-VLM proof — NOT a real-model proof.
|
|
20
20
|
|
|
21
|
+
bench (workflow_dispatch only):
|
|
22
|
+
Provisions exactly as 'real' does, then runs scripts/bench-local-vlm.mjs
|
|
23
|
+
instead of the pass/fail verification — so the run MEASURES this machine's
|
|
24
|
+
per-frame cost and grades it against the throughput floor, rather than
|
|
25
|
+
asserting a person was seen.
|
|
26
|
+
This is the only way a Windows number exists at all. windows-latest has
|
|
27
|
+
failed -Mode real 8 of 8 times since 2026-06-29 (each attempt: two 360 s
|
|
28
|
+
request timeouts, one per delegate) and therefore produced NO per-frame
|
|
29
|
+
figure, so every latency number in the capacity plan came off one Apple M4
|
|
30
|
+
Max. A bench run bounds itself with -BenchBudgetMinutes and writes its JSON
|
|
31
|
+
after every frame, because a process killed at the job cap writes nothing.
|
|
32
|
+
|
|
21
33
|
real (workflow_dispatch / scheduled only):
|
|
22
34
|
Provisions litert-lm + imports Gemma 4 E2B (setup-litertlm.ps1, model cached),
|
|
23
35
|
waits for the real `litert-lm serve` :9379 to be healthy, then runs the REAL
|
|
@@ -29,20 +41,44 @@
|
|
|
29
41
|
different schema and a different prompt, so the audience arm cannot catch a
|
|
30
42
|
regression in it; it is also the set 166 of the 176 active prod profiles run.
|
|
31
43
|
|
|
32
|
-
.PARAMETER Mode 'wiring' (default) or '
|
|
44
|
+
.PARAMETER Mode 'wiring' (default), 'real' or 'bench'.
|
|
33
45
|
.PARAMETER Frame Person JPEG fixture. Default: e2e/fixtures/person.jpg.
|
|
34
|
-
.PARAMETER Port litert-lm serve port (real mode). Default 9379.
|
|
46
|
+
.PARAMETER Port litert-lm serve port (real/bench mode). Default 9379.
|
|
35
47
|
.PARAMETER FfmpegPath ffmpeg for the connector's RTSP capture (wiring mode).
|
|
36
48
|
Default: the bundled bin\ffmpeg.exe if staged, else 'ffmpeg'.
|
|
49
|
+
.PARAMETER BenchArms bench mode: which arms to run, in priority order — the
|
|
50
|
+
budget cuts from the END, so the shipping config leads.
|
|
51
|
+
.PARAMETER BenchFrames bench mode: which committed CCTV frames to measure.
|
|
52
|
+
.PARAMETER BenchRounds bench mode: interleaved rounds per arm.
|
|
53
|
+
.PARAMETER BenchBudgetMinutes bench mode: wall-clock ceiling, set BELOW the job
|
|
54
|
+
cap so the run stops with results written instead of
|
|
55
|
+
being killed with none.
|
|
56
|
+
.PARAMETER BenchFrameTimeoutMinutes bench mode: per-frame deadline. Generous on
|
|
57
|
+
purpose: a frame that times out records the DEADLINE, not
|
|
58
|
+
the machine's speed, which is exactly how windows-latest
|
|
59
|
+
has produced no number for two months.
|
|
60
|
+
.PARAMETER BenchOut bench mode: where the JSON matrix lands.
|
|
61
|
+
.PARAMETER BenchModel bench mode: a NON-default .litertlm model id, for the
|
|
62
|
+
per-silicon A/B (litert-community ships _intel_LNL /
|
|
63
|
+
_intel_PTL builds alongside the generic file we import
|
|
64
|
+
everywhere). Import it first with
|
|
65
|
+
`litert-lm import --from-huggingface-repo ...`.
|
|
37
66
|
|
|
38
67
|
.OUTPUTS exit 0 = E2E passed; exit 1 = failed.
|
|
39
68
|
#>
|
|
40
69
|
[CmdletBinding()]
|
|
41
70
|
param(
|
|
42
|
-
[ValidateSet('wiring', 'real')][string]$Mode = 'wiring',
|
|
71
|
+
[ValidateSet('wiring', 'real', 'bench')][string]$Mode = 'wiring',
|
|
43
72
|
[string]$Frame,
|
|
44
73
|
[string]$Port = '9379',
|
|
45
|
-
[string]$FfmpegPath
|
|
74
|
+
[string]$FfmpegPath,
|
|
75
|
+
[string]$BenchArms = 'cpu-sop,gpu-sop,cpu-dooh-sop',
|
|
76
|
+
[string]$BenchFrames = 'kitchen-5-people',
|
|
77
|
+
[int]$BenchRounds = 1,
|
|
78
|
+
[int]$BenchBudgetMinutes = 40,
|
|
79
|
+
[int]$BenchFrameTimeoutMinutes = 20,
|
|
80
|
+
[string]$BenchOut,
|
|
81
|
+
[string]$BenchModel
|
|
46
82
|
)
|
|
47
83
|
$ErrorActionPreference = 'Stop'
|
|
48
84
|
Set-StrictMode -Version Latest
|
|
@@ -113,8 +149,15 @@ if ($Mode -eq 'wiring') {
|
|
|
113
149
|
exit 0
|
|
114
150
|
}
|
|
115
151
|
|
|
116
|
-
# ─── Mode: real (actual Gemma 4 E2B via litert-lm serve)
|
|
117
|
-
|
|
152
|
+
# ─── Mode: real / bench (actual Gemma 4 E2B via litert-lm serve) ──────────────
|
|
153
|
+
# Provisioning, serve start-up and health are IDENTICAL for both: 'real' then
|
|
154
|
+
# asserts, 'bench' then measures. One provisioning path, so a Windows number and
|
|
155
|
+
# a Windows pass/fail are statements about the same install.
|
|
156
|
+
if ($Mode -eq 'bench') {
|
|
157
|
+
Log "HARDWARE MATRIX — provisioning litert-lm + Gemma 4 E2B, then MEASURING this machine"
|
|
158
|
+
} else {
|
|
159
|
+
Log "REAL-MODEL SMOKE — provisioning litert-lm + Gemma 4 E2B, then real inference"
|
|
160
|
+
}
|
|
118
161
|
|
|
119
162
|
# 1. Provision litert-lm + import the model (idempotent; model may be cached by
|
|
120
163
|
# the workflow's actions/cache step before this runs).
|
|
@@ -174,6 +217,54 @@ if (-not $healthy) {
|
|
|
174
217
|
}
|
|
175
218
|
Log "litert-lm serve healthy on :$Port"
|
|
176
219
|
|
|
220
|
+
# 3b. BENCH: measure this machine instead of asserting on it.
|
|
221
|
+
if ($Mode -eq 'bench') {
|
|
222
|
+
if (-not $BenchOut) {
|
|
223
|
+
$benchBase = if ([string]::IsNullOrWhiteSpace($env:RUNNER_TEMP)) { $env:TEMP } else { $env:RUNNER_TEMP }
|
|
224
|
+
$BenchOut = Join-Path $benchBase 'bench-local-vlm.json'
|
|
225
|
+
}
|
|
226
|
+
$bench = Join-Path $PkgRoot 'scripts\bench-local-vlm.mjs'
|
|
227
|
+
if (-not (Test-Path $bench)) { Die "bench runner missing: $bench" }
|
|
228
|
+
# The machine itself is read from `os` by the bench; this note only records
|
|
229
|
+
# WHICH instance of that machine class ran, so a CI row is traceable to a run.
|
|
230
|
+
$note = if ($env:GITHUB_ACTIONS -eq 'true') {
|
|
231
|
+
"GitHub-hosted runner, image $($env:ImageOS)/$($env:ImageVersion), run $($env:GITHUB_RUN_ID)"
|
|
232
|
+
} else { 'local Windows machine' }
|
|
233
|
+
Log "running the hardware matrix — arms=$BenchArms frames=$BenchFrames rounds=$BenchRounds budget=${BenchBudgetMinutes}m"
|
|
234
|
+
# Initialised BEFORE the try: if `node` cannot start at all, the failure
|
|
235
|
+
# message below still has a value to report instead of tripping StrictMode.
|
|
236
|
+
$benchExit = -1
|
|
237
|
+
try {
|
|
238
|
+
# Built as an ARRAY and splatted rather than a backticked line ending in a
|
|
239
|
+
# conditional array: an empty @() as the trailing argument to a native
|
|
240
|
+
# command expands to an empty string under Windows PowerShell 5.1, which
|
|
241
|
+
# node would read as a stray positional argument.
|
|
242
|
+
$benchArgs = @(
|
|
243
|
+
$bench,
|
|
244
|
+
'--litert', "http://127.0.0.1:$Port",
|
|
245
|
+
'--arms', $BenchArms,
|
|
246
|
+
'--frames', $BenchFrames,
|
|
247
|
+
'--rounds', [string]$BenchRounds,
|
|
248
|
+
'--budget-ms', [string]($BenchBudgetMinutes * 60000),
|
|
249
|
+
'--timeout-ms', [string]($BenchFrameTimeoutMinutes * 60000),
|
|
250
|
+
'--machine-note', $note,
|
|
251
|
+
'--out', $BenchOut
|
|
252
|
+
)
|
|
253
|
+
if ($BenchModel) { $benchArgs += @('--model', $BenchModel) }
|
|
254
|
+
node @benchArgs
|
|
255
|
+
$benchExit = $LASTEXITCODE
|
|
256
|
+
} finally {
|
|
257
|
+
if ($serveProc) { try { $serveProc.Kill() } catch {} }
|
|
258
|
+
}
|
|
259
|
+
if (Test-Path $BenchOut) { Log "matrix written: $BenchOut" }
|
|
260
|
+
# A bench REPORTS; it does not gate. Exiting non-zero on a slow machine would
|
|
261
|
+
# turn "this box is too slow" into "the lane is broken", which is the confusion
|
|
262
|
+
# that left windows-latest unmeasured. Only a crash (no JSON at all) fails.
|
|
263
|
+
if (-not (Test-Path $BenchOut)) { Die "bench produced no matrix at all (node exit $benchExit)" }
|
|
264
|
+
Pass "hardware matrix measured on this machine (see $BenchOut)."
|
|
265
|
+
exit 0
|
|
266
|
+
}
|
|
267
|
+
|
|
177
268
|
# 4. REAL on-device inference on the person fixture + assert a person was seen.
|
|
178
269
|
# BOTH field sets are exercised, because the connector ships both and they are
|
|
179
270
|
# different prompts against a different schema:
|
|
@@ -121,7 +121,17 @@ export interface CameraHealthReport {
|
|
|
121
121
|
*/
|
|
122
122
|
captureProof?: 'decoded_frame' | 'stream_open';
|
|
123
123
|
}
|
|
124
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* Minimal injectable HTTP transport — lets tests stub the network entirely.
|
|
126
|
+
*
|
|
127
|
+
* `headers` is OPTIONAL on the response so every existing stub that returns
|
|
128
|
+
* `{ statusCode, body }` keeps compiling. It exists for exactly one reason:
|
|
129
|
+
* HTTP Digest is a CHALLENGE-response scheme, and the challenge arrives only in
|
|
130
|
+
* the 401's `WWW-Authenticate` header. A transport that discards response
|
|
131
|
+
* headers cannot speak Digest at all — which is why `OnvifClient` could not
|
|
132
|
+
* authenticate against AXIS OS 12.11 (2026-08-18 camera-interop validation).
|
|
133
|
+
* Header names are lowercased by Node; read them that way.
|
|
134
|
+
*/
|
|
125
135
|
export interface HttpPoster {
|
|
126
136
|
(url: string, options: {
|
|
127
137
|
method: string;
|
|
@@ -130,6 +140,7 @@ export interface HttpPoster {
|
|
|
130
140
|
}, body: string): Promise<{
|
|
131
141
|
statusCode: number;
|
|
132
142
|
body: string;
|
|
143
|
+
headers?: Record<string, string | string[] | undefined>;
|
|
133
144
|
}>;
|
|
134
145
|
}
|
|
135
146
|
export declare class AudienceAnalyzeClient {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudienceAnalyzeClient.d.ts","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,4BAA4B;IAC3C,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrC,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5F,MAAM,MAAM,wBAAwB,GAChC,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,UAAU,GACV,WAAW,GACX,cAAc;AAChB;;;;;;;;;;;;;;;GAeG;GACD,sBAAsB,CAAC;AAE3B,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,WAAW,GACX,QAAQ,GACR,sBAAsB,GACtB,aAAa,CAAC;AAElB,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,iBAAiB,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC;CAChD;AAED
|
|
1
|
+
{"version":3,"file":"AudienceAnalyzeClient.d.ts","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudienceAnalyzeClient.js","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,6CAA+B;AAC/B,6BAA0B;AAC1B,mCAAoC;AAEpC,2DAAiG;
|
|
1
|
+
{"version":3,"file":"AudienceAnalyzeClient.js","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"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"}
|
package/dist/ChannelProber.d.ts
CHANGED
|
@@ -170,6 +170,28 @@ export declare function grabOneFrameAnyTransport(rtspUrl: string, opts: {
|
|
|
170
170
|
timeoutMs?: number;
|
|
171
171
|
spawner?: typeof spawn;
|
|
172
172
|
}): Promise<TransportFrameGrab>;
|
|
173
|
+
/**
|
|
174
|
+
* The extra sentence to show when a login that ONVIF/REST accepted is refused
|
|
175
|
+
* by RTSP, and the username is not already lowercase.
|
|
176
|
+
*
|
|
177
|
+
* Measured on Network Optix Nx Meta 6.1.2.42921 (2026-08-18): the REST session
|
|
178
|
+
* API accepted the configured `CodiStream`, while RTSP Digest answered
|
|
179
|
+
* `X-Auth-Result: Auth_WrongPassword` for that exact spelling and succeeded
|
|
180
|
+
* immediately as `codistream`. Same account, same password, same camera rights.
|
|
181
|
+
*
|
|
182
|
+
* Without this the case renders as the generic "accepted the ONVIF login but
|
|
183
|
+
* refused RTSP streaming (check live-view/RTSP permission)" — which sends the
|
|
184
|
+
* installer into the recorder's permission editor for a defect that lives in
|
|
185
|
+
* the username's CAPITALISATION, and the permissions they find there are
|
|
186
|
+
* already correct. That is the misdirection class, not a missing message.
|
|
187
|
+
*
|
|
188
|
+
* Reported, never auto-retried: a silent second login with a different spelling
|
|
189
|
+
* spends the account's lockout budget (recorders lock after ~5 bad logins) to
|
|
190
|
+
* test a guess, and on every recorder that is genuinely case-SENSITIVE it buys
|
|
191
|
+
* nothing. Returns null when the username is already lowercase, i.e. when this
|
|
192
|
+
* cannot be the cause.
|
|
193
|
+
*/
|
|
194
|
+
export declare function usernameCaseMismatchHint(username: string | undefined): string | null;
|
|
173
195
|
/** Map ffmpeg's stderr to a failure class the portal can act on. */
|
|
174
196
|
export declare function classifyFfmpegStderr(stderr: string): {
|
|
175
197
|
failureClass: ProbeFailureClass;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelProber.d.ts","sourceRoot":"","sources":["../src/ChannelProber.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ChannelProber.d.ts","sourceRoot":"","sources":["../src/ChannelProber.ts"],"names":[],"mappings":"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"}
|
package/dist/ChannelProber.js
CHANGED
|
@@ -47,6 +47,7 @@ exports.directStreamChannelKey = directStreamChannelKey;
|
|
|
47
47
|
exports.sanitizeRtspUrlForLog = sanitizeRtspUrlForLog;
|
|
48
48
|
exports.grabOneFrame = grabOneFrame;
|
|
49
49
|
exports.grabOneFrameAnyTransport = grabOneFrameAnyTransport;
|
|
50
|
+
exports.usernameCaseMismatchHint = usernameCaseMismatchHint;
|
|
50
51
|
exports.classifyFfmpegStderr = classifyFfmpegStderr;
|
|
51
52
|
exports.probeHost = probeHost;
|
|
52
53
|
const child_process_1 = require("child_process");
|
|
@@ -539,6 +540,35 @@ async function grabOneFrameAnyTransport(rtspUrl, opts) {
|
|
|
539
540
|
}
|
|
540
541
|
return strongestFailure || { ok: false, failureClass: 'no_frames', message: 'stream produced no frame' };
|
|
541
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* The extra sentence to show when a login that ONVIF/REST accepted is refused
|
|
545
|
+
* by RTSP, and the username is not already lowercase.
|
|
546
|
+
*
|
|
547
|
+
* Measured on Network Optix Nx Meta 6.1.2.42921 (2026-08-18): the REST session
|
|
548
|
+
* API accepted the configured `CodiStream`, while RTSP Digest answered
|
|
549
|
+
* `X-Auth-Result: Auth_WrongPassword` for that exact spelling and succeeded
|
|
550
|
+
* immediately as `codistream`. Same account, same password, same camera rights.
|
|
551
|
+
*
|
|
552
|
+
* Without this the case renders as the generic "accepted the ONVIF login but
|
|
553
|
+
* refused RTSP streaming (check live-view/RTSP permission)" — which sends the
|
|
554
|
+
* installer into the recorder's permission editor for a defect that lives in
|
|
555
|
+
* the username's CAPITALISATION, and the permissions they find there are
|
|
556
|
+
* already correct. That is the misdirection class, not a missing message.
|
|
557
|
+
*
|
|
558
|
+
* Reported, never auto-retried: a silent second login with a different spelling
|
|
559
|
+
* spends the account's lockout budget (recorders lock after ~5 bad logins) to
|
|
560
|
+
* test a guess, and on every recorder that is genuinely case-SENSITIVE it buys
|
|
561
|
+
* nothing. Returns null when the username is already lowercase, i.e. when this
|
|
562
|
+
* cannot be the cause.
|
|
563
|
+
*/
|
|
564
|
+
function usernameCaseMismatchHint(username) {
|
|
565
|
+
if (!username || username === username.toLowerCase())
|
|
566
|
+
return null;
|
|
567
|
+
return (` The username "${username}" contains uppercase letters. Some recorders — Network Optix ` +
|
|
568
|
+
'Nx Witness/Nx Meta among them — accept the mixed-case spelling for the ONVIF/REST login ' +
|
|
569
|
+
`but normalise RTSP usernames to lowercase, so the same account is refused only on the ` +
|
|
570
|
+
`stream. Try "${username.toLowerCase()}".`);
|
|
571
|
+
}
|
|
542
572
|
/** Map ffmpeg's stderr to a failure class the portal can act on. */
|
|
543
573
|
function classifyFfmpegStderr(stderr) {
|
|
544
574
|
// Classify on CREDENTIAL-FREE text, and match status codes as whole tokens.
|
|
@@ -731,7 +761,8 @@ async function probeHost(target, opts = {}) {
|
|
|
731
761
|
channelKey: key,
|
|
732
762
|
status: 'failed',
|
|
733
763
|
failureClass: 'rtsp_forbidden',
|
|
734
|
-
message: 'Recorder accepted the ONVIF login but refused RTSP streaming (check live-view/RTSP permission).'
|
|
764
|
+
message: 'Recorder accepted the ONVIF login but refused RTSP streaming (check live-view/RTSP permission).' +
|
|
765
|
+
(usernameCaseMismatchHint(target.username) ?? ''),
|
|
735
766
|
name: profile.name || undefined,
|
|
736
767
|
brand,
|
|
737
768
|
host,
|
|
@@ -779,7 +810,8 @@ async function probeHost(target, opts = {}) {
|
|
|
779
810
|
channelKey: key,
|
|
780
811
|
status: 'failed',
|
|
781
812
|
failureClass: 'rtsp_forbidden',
|
|
782
|
-
message: 'Recorder accepted the ONVIF login but refused RTSP streaming (check live-view/RTSP permission).'
|
|
813
|
+
message: 'Recorder accepted the ONVIF login but refused RTSP streaming (check live-view/RTSP permission).' +
|
|
814
|
+
(usernameCaseMismatchHint(target.username) ?? ''),
|
|
783
815
|
name: profile.name || undefined,
|
|
784
816
|
brand,
|
|
785
817
|
host,
|
|
@@ -831,13 +863,25 @@ async function probeHost(target, opts = {}) {
|
|
|
831
863
|
// ONVIF creds were ACCEPTED — an RTSP 401 here is a PERMISSION
|
|
832
864
|
// problem (account can't stream), not a password problem.
|
|
833
865
|
const failureClass = grab.failureClass === 'rtsp_auth' ? 'rtsp_forbidden' : grab.failureClass;
|
|
866
|
+
// The device may have advertised a stream URI that cannot serve
|
|
867
|
+
// media (an HTTP port-forward mapping). Attach that only when we
|
|
868
|
+
// actually used the advertised URI and it actually failed, so a
|
|
869
|
+
// working camera never carries a warning and a timeout that has a
|
|
870
|
+
// NAMED cause stops reading as an anonymous one.
|
|
871
|
+
const advertisedPortNote = !skipKnownBadOnvifUri && failureClass !== 'empty_channel'
|
|
872
|
+
? client
|
|
873
|
+
.getStreamUriWarnings()
|
|
874
|
+
.find((w) => w.profileToken === profile.token)?.message
|
|
875
|
+
: undefined;
|
|
834
876
|
await emit({
|
|
835
877
|
channelKey: key,
|
|
836
878
|
status: failureClass === 'empty_channel' ? 'empty' : 'failed',
|
|
837
879
|
failureClass,
|
|
838
880
|
message: failureClass === 'empty_channel'
|
|
839
881
|
? 'No camera image detected on this channel.'
|
|
840
|
-
:
|
|
882
|
+
: advertisedPortNote
|
|
883
|
+
? `${grab.message} ${advertisedPortNote}`
|
|
884
|
+
: grab.message,
|
|
841
885
|
name: profile.name || undefined,
|
|
842
886
|
brand,
|
|
843
887
|
host,
|