Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
80aa15a
docs: define application platform architecture
tulayha Jul 28, 2026
7d728c3
feat: centralize application and modernize CPU providers
tulayha Jul 28, 2026
1b1e3ee
refactor: enforce application platform boundaries
tulayha Jul 28, 2026
7602c1b
feat: add durable multi-media index snapshots
tulayha Jul 28, 2026
f43a8c3
feat: add managed media and artifact catalogs
tulayha Jul 28, 2026
686c9b9
feat: add durable background jobs
tulayha Jul 28, 2026
910a0cd
feat: add authenticated http api
tulayha Jul 29, 2026
3e4bbad
fix: harden local execution boundaries
tulayha Jul 29, 2026
6eb7be4
refactor: centralize application entry points
tulayha Jul 29, 2026
a3c8e85
feat: add remote ingestion deployment
tulayha Jul 29, 2026
19e479b
feat: add model context protocol server
tulayha Jul 29, 2026
5830c8d
feat: add grounded multimodal queries
tulayha Jul 29, 2026
baa64e2
feat: add desktop application bootstrap
tulayha Jul 29, 2026
b600164
docs: evaluate gpu worker compatibility
tulayha Jul 29, 2026
51a3be9
fix: close release smoke gaps
tulayha Jul 29, 2026
76c95b7
refactor: simplify server storage topology
tulayha Jul 29, 2026
fa7137e
fix: stabilize storage and publication foundations
tulayha Jul 29, 2026
5b5d52e
fix: stream dependency check progress
tulayha Jul 29, 2026
4048c10
fix: report long-running CLI progress
tulayha Jul 29, 2026
009863d
fix: simplify dependency check output
tulayha Jul 29, 2026
0cbbe3c
fix: standardize dependency check details
tulayha Jul 29, 2026
6856082
feat: normalize scene sampling cadence
tulayha Jul 29, 2026
a398cf0
fix: restore local indexing usability
tulayha Jul 29, 2026
8aaca35
fix: make model preparation explicit
tulayha Jul 29, 2026
61c5e2c
fix: align local storage and model readiness
tulayha Jul 29, 2026
711f22f
fix: use capability details in frontend
tulayha Jul 29, 2026
a49ee6f
fix: clarify frontend search behavior
tulayha Jul 29, 2026
3b567d6
fix: keep frontend search form submittable
tulayha Jul 29, 2026
75c2a5b
test: add full-page frontend regressions
tulayha Jul 29, 2026
dae2efd
feat(branding): share app icon across interfaces
tulayha Jul 29, 2026
00516aa
feat(mcp): improve setup and media discovery
tulayha Jul 29, 2026
daf119d
feat(cli): add MCP self-check and index listing
tulayha Jul 29, 2026
8da5d55
feat(artifacts): expose clip downloads across interfaces
tulayha Jul 29, 2026
41c6b4f
feat(runtime): add guided ffmpeg initialization
tulayha Jul 29, 2026
e27ac3a
docs: prepare public release documentation
tulayha Jul 29, 2026
880da78
docs: restore release detail and simplify setup
tulayha Jul 29, 2026
9ef2cbc
fix(benchmarks): preserve multi-video run identity
tulayha Jul 30, 2026
1bafc6a
feat(benchmarks): add guided input preparation
tulayha Jul 30, 2026
182c27c
feat: ship managed desktop runtime and release artifacts
tulayha Jul 30, 2026
8fbbeaa
fix(ci): reduce pull request fan-out
tulayha Jul 30, 2026
d901118
fix(ci): restrict desktop pull request target
tulayha Jul 30, 2026
c901c47
fix(test): normalize styled CLI help
tulayha Jul 30, 2026
5cf1ac7
fix(desktop): repair managed runtime setup
tulayha Jul 30, 2026
4eccbcd
ci: cache desktop builds and remove duplicate work
tulayha Jul 30, 2026
0409c5a
fix(ci): align model-free container smoke
tulayha Jul 30, 2026
3db529a
docs: refocus README on the product
tulayha Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
desktop/runtime-constraints.txt text eol=lf
181 changes: 161 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ on:
- opened
- synchronize
- reopened
workflow_call:
inputs:
checkout_ref:
description: Exact commit to validate.
required: false
type: string
full:
description: Run every validation surface without PR path scoping.
required: false
default: false
type: boolean
skip_containers:
description: Skip container validation when a downstream release job builds and smokes the same images.
required: false
default: false
type: boolean

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -18,26 +34,47 @@ permissions:
jobs:
validate:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ${{ fromJSON(inputs.full && '["3.11","3.12","3.13","3.14"]' || '["3.14"]') }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
ref: ${{ inputs.checkout_ref || github.sha }}

- name: Determine validation scope
id: scope
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
FORCE_FULL: ${{ inputs.full || false }}
SKIP_CONTAINERS: ${{ inputs.skip_containers || false }}
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
if [[ "$FORCE_FULL" == "true" ]]; then
{
echo "run_suite=true"
if [[ "$SKIP_CONTAINERS" == "true" ]]; then
echo "run_container=false"
else
echo "run_container=true"
fi
echo "require_changelog=false"
echo "needs_python=true"
} >> "$GITHUB_OUTPUT"
exit 0
fi

changed_files="$(git diff --name-only "$BASE_SHA" HEAD)"
if grep -Eq '^(\.github/workflows/ci\.yml$|src/|tests/|utils/|LICENSE$|MANIFEST\.in$|pyproject\.toml$)' <<< "$changed_files"; then
if grep -Eq '^(\.github/workflows/ci\.yml$|src/|tests/|utils/|LICENSE$|MANIFEST\.in$|pyproject\.toml$|uv\.lock$)' <<< "$changed_files"; then
run_suite=true
else
run_suite=false
fi
if grep -Eq '^(\.dockerignore$|\.github/workflows/ci\.yml$|Dockerfile$|compose\.yaml$|pyproject\.toml$|src/vidxp/(requirements/.*\.txt|capabilities/[^/]+/requirements\.txt)$)' <<< "$changed_files"; then
if grep -Eq '^(\.dockerignore$|\.github/workflows/ci\.yml$|Dockerfile$|compose\.yaml$|pyproject\.toml$|uv\.lock$|src/vidxp/(requirements/.*\.txt|capabilities/[^/]+/requirements\.txt)$)' <<< "$changed_files"; then
run_container=true
else
run_container=false
Expand Down Expand Up @@ -67,7 +104,7 @@ jobs:
- uses: actions/setup-python@v7
if: steps.scope.outputs.needs_python == 'true'
with:
python-version: "3.11"
python-version: ${{ matrix.python-version }}
cache: pip

- name: Install repository tooling
Expand All @@ -77,29 +114,39 @@ jobs:
python -m pip install -r utils/build-requirements.txt

- name: Require a changelog fragment
if: steps.scope.outputs.require_changelog == 'true'
if: steps.scope.outputs.require_changelog == 'true' && matrix.python-version == '3.14'
run: towncrier check --compare-with "${{ github.event.pull_request.base.sha }}"

- name: Install test surface
if: steps.scope.outputs.run_suite == 'true'
run: python -m pip install ".[scene,frontend,benchmarks]"
run: |
python -m pip install "uv==0.12.0"
uv sync \
--frozen \
--extra all \
--extra frontend \
--extra benchmarks \
--extra server \
--extra slm \
--extra test \
--no-dev

- name: Lint
if: steps.scope.outputs.run_suite == 'true'
if: steps.scope.outputs.run_suite == 'true' && matrix.python-version == '3.14'
run: ruff check src tests

- name: Test
if: steps.scope.outputs.run_suite == 'true'
run: python -m unittest discover -s tests -q
run: uv run --no-sync python -m unittest discover -s tests -q
env:
PYTHONPATH: src

- name: Build wheel and source distribution
if: steps.scope.outputs.run_suite == 'true'
if: steps.scope.outputs.run_suite == 'true' && matrix.python-version == '3.14'
run: python -m build

- name: Verify minimal wheel
if: steps.scope.outputs.run_suite == 'true'
if: steps.scope.outputs.run_suite == 'true' && matrix.python-version == '3.14'
shell: bash
run: |
python -m venv .wheel-smoke
Expand All @@ -111,47 +158,55 @@ jobs:
from subprocess import check_output

import vidxp
from vidxp.capabilities.registry import capability_names
from vidxp.capabilities.registry import create_capability_registry

assert capability_names() == ("dialogue", "scene", "actor")
assert create_capability_registry().names() == (
"dialogue", "scene", "actor"
)
help_text = check_output(
[".wheel-smoke/bin/vidxp", "--help"],
text=True,
)
assert "benchmark" not in help_text
assert "benchmark" in help_text
benchmark_help = check_output(
[".wheel-smoke/bin/vidxp", "benchmark", "--help"],
text=True,
)
assert "official benchmark adapters" in benchmark_help
for module in (
"chromadb",
"clip",
"cv2",
"face_recognition",
"faster_whisper",
"sentence_transformers",
"srt",
"streamlit",
"torch",
"whisperx",
"transformers",
):
assert find_spec(module) is None, module
PY

- name: Validate Compose configuration
if: steps.scope.outputs.run_container == 'true'
if: steps.scope.outputs.run_container == 'true' && matrix.python-version == '3.14'
run: docker compose config --quiet

- name: Build container
if: steps.scope.outputs.run_container == 'true'
if: steps.scope.outputs.run_container == 'true' && matrix.python-version == '3.14'
run: docker build --tag vidxp:ci .

- name: Smoke container
if: steps.scope.outputs.run_container == 'true'
if: steps.scope.outputs.run_container == 'true' && matrix.python-version == '3.14'
shell: bash
run: |
docker run --detach --name vidxp-ci \
--publish 127.0.0.1:8501:8501 vidxp:ci
trap 'docker rm --force vidxp-ci >/dev/null 2>&1 || true' EXIT

docker exec vidxp-ci vidxp --version
docker exec vidxp-ci vidxp init --json
docker exec vidxp-ci python -c \
'import clip, face_recognition, whisperx'
'import chromadb, cv2, faster_whisper, huggingface_hub, pooch, psutil, sentence_transformers, torch, transformers; assert psutil.virtual_memory().available > 0'
docker exec vidxp-ci python -c \
'import importlib.metadata as m; assert not any(d.metadata["Name"].lower().startswith("nvidia-") for d in m.distributions())'
docker exec vidxp-ci sh -c \
'test ! -d "$HOME/.cache/huggingface" && test ! -d "$HOME/.cache/clip"'

Expand All @@ -167,3 +222,89 @@ jobs:

docker logs vidxp-ci
exit 1

provider-platform-smoke:
name: CPU providers (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ${{ fromJSON(inputs.full && '["ubuntu-24.04","windows-2025","macos-15"]' || '["windows-2025"]') }}
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.checkout_ref || github.sha }}

- uses: actions/setup-python@v7
with:
python-version: "3.14"

- name: Install locked local-worker environment
run: |
python -m pip install "uv==0.12.0"
uv sync --frozen --extra local-worker --no-dev

- name: Verify provider contracts without model downloads
run: |
uv run --no-sync python -m unittest discover -s tests -p "test_models.py" -q
uv run --no-sync python -m unittest discover -s tests -p "test_indexing.py" -q
env:
PYTHONPATH: src
VIDXP_ALLOW_MODEL_DOWNLOADS: "false"

- name: Verify platform and CPU runtime
shell: bash
run: |
uv run --no-sync python - <<'PY'
from importlib import metadata
import platform
import chromadb
import cv2
import faster_whisper
import huggingface_hub
import pooch
import psutil
import sentence_transformers
import torch
import transformers

from vidxp.runtime import resolve_backends

assert hasattr(cv2, "FaceDetectorYN")
assert hasattr(cv2, "FaceRecognizerSF")
assert hasattr(faster_whisper, "WhisperModel")
assert hasattr(faster_whisper, "BatchedInferencePipeline")
assert hasattr(
sentence_transformers.SentenceTransformer,
"encode_query",
)
assert hasattr(
sentence_transformers.SentenceTransformer,
"encode_document",
)
assert hasattr(transformers, "AutoModel")
assert hasattr(transformers, "AutoProcessor")
assert hasattr(chromadb, "PersistentClient")
assert hasattr(huggingface_hub, "snapshot_download")
assert hasattr(pooch, "retrieve")
assert psutil.virtual_memory().available > 0
assert torch.version.cuda is None, torch.version.cuda
installed = {
distribution.metadata["Name"].lower().replace("_", "-")
for distribution in metadata.distributions()
if distribution.metadata.get("Name")
}
leaks = sorted(
name
for name in installed
if name in {"cuda-toolkit", "cuda-bindings", "triton"}
or name.startswith("nvidia-")
or name.startswith("pytorch-triton")
)
assert not leaks, leaks

profile = resolve_backends("cpu")
assert profile.torch_device == "cpu"
if platform.system() == "Darwin":
assert platform.machine() == "arm64"
PY
Loading
Loading