Add new sample application - Agent Predictive Maintenance Pipeline#2479
Draft
madhuri-rai07 wants to merge 18 commits into
Draft
Add new sample application - Agent Predictive Maintenance Pipeline#2479madhuri-rai07 wants to merge 18 commits into
madhuri-rai07 wants to merge 18 commits into
Conversation
Blueprint SA for multi-agent industrial defect detection pipeline. Config-driven: new use case = 4 files, no code changes. Services (new): - storage-service: SQLite REST API with WAL mode, Prometheus metrics - agent-service: LangGraph 4-agent pipeline (policy/analysis/evidence/ticketing) with MQTT subscriber, fallback/LLM modes, FastAPI REST wrapper - ui-service: FastAPI web dashboard with Jinja2 templates Reused microservices: - dlstreamer-pipeline-server, vlm-openvino-serving, model-download, metrics-manager Infrastructure: - 5 Docker Compose files (base/agents/llm/ui/telemetry) - nginx, mosquitto, prometheus configs - setup.sh one-command launcher with --use-case, --stop, --clean-data Use case: pipeline-defect-detection - agents.yaml, policy_fallback.json, pipeline-server-config.json - Prompt file with SYSTEM/POLICY/ANALYSIS/EVIDENCE/TICKETING sections - .env file for deployment config Tests: 31 unit tests (18 storage + 9 agent + 4 ui), all passing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
agent-service: - fastapi 0.115.12 → 0.136.3 - uvicorn 0.34.3 → 0.49.0 - pydantic 2.11.4 → 2.13.4 - langgraph 0.4.8 → 1.2.4 - openai 1.84.0 → 2.41.1 - pyyaml 6.0.2 → 6.0.3 - requests 2.32.3 → 2.34.2 - paho-mqtt 2.1.0 (unchanged, already latest) - REMOVED: langchain-openai (not directly imported) - REMOVED: langchain-core (transitive dep of langgraph) - REMOVED: jinja2 (only used in ui-service) storage-service: - fastapi 0.115.12 → 0.136.3 - uvicorn 0.34.3 → 0.49.0 - pydantic 2.11.4 → 2.13.4 ui-service: - fastapi 0.115.12 → 0.136.3 - uvicorn 0.34.3 → 0.49.0 - pydantic 2.11.4 → 2.13.4 - jinja2 3.1.6, httpx 0.28.1 (unchanged, already latest) All 31 tests pass with updated deps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
python:3.12-slim does not include curl, causing all three new services (apm-storage, apm-agent, apm-ui) to fail their Docker healthchecks and be marked unhealthy immediately after startup. Replace curl with Python stdlib urllib.request.urlopen() which is always available in the Python base image and needs no extra packages: compose.base.yaml (apm-storage :5001) compose.agents.yaml (apm-agent :5002) compose.ui.yaml (apm-ui :5003) compose.llm.yaml left unchanged — vlm-openvino-serving is a reused Intel image that ships with curl. Fixes: container apm-storage is unhealthy / dependency failed to start. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three mismatches between the compose environment block and what the agent-service Python modules actually read via os.environ.get(): PROMPTS_DIR → USE_CASE_PROMPTS_DIR (prompt_loader.py, main.py) POLICY_FALLBACK_PATH → FALLBACK_POLICY_PATH (llm_client.py) (missing) + USE_CASE_CONFIGS_DIR (config_loader.py, llm_client.py) These caused the runtime error: 'Prompt file not found: /configs/prompts/pipeline-defect-detection.txt' because USE_CASE_PROMPTS_DIR was unset so prompt_loader.py fell back to the /configs/prompts default path instead of /app/prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…oot volume
- Rewrite pipeline-server-config.json to match DL Streamer Pipeline Server
2026.x format: {"config": {"pipelines": [...]}} with GStreamer pipeline
strings instead of the incorrect flat config[] array with shell vars
- Remove ${VAR} shell substitution that DL Streamer does not evaluate
- Add CPU (auto_start=true), GPU, and NPU pipeline variants matching
IEI-Vision reference pattern
- Specify model path directly in gvadetect element
- Add apm_pipeline_root named volume in compose.base.yaml to fix
PermissionError on /var/cache/pipeline_root at container startup
- Mount USE_CASE_RESOURCES_DIR to /home/pipeline-server/resources so
sample video is accessible inside the container
- Export USE_CASE_RESOURCES_DIR in setup.sh alongside other USE_CASE_* vars
- Add resources/videos/README.md with instructions for placing sample video
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adapted from intel/predictive-maintenance-pipeline with blueprint-specific
integration:
- scripts/download_and_prep_data.py
* Downloads dataset from URL (e.g. Kaggle pipeline-defect-dataset)
* Splits into 90/10 train/val in YOLO format under datasets/<use_case>/
* Creates sample.mp4 from val images directly at
apps/<use-case>/resources/videos/sample.mp4 (the path DL Streamer reads)
* Supports --use-case flag matching our blueprint naming convention
* Supports gas-detection use case via stratified class split
* Supports --train-ratio, --seed, --keep-download options
- setup.sh
* Warns if sample.mp4 is missing and prints the prep command to run
* Points to LLM_MODE=fallback as the no-video alternative
- README.md
* Added step 2 documenting the data prep workflow with Kaggle URL
* Added DISCLAIMER notice for dataset licensing
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sionError Named Docker volumes are created root-owned; DL Streamer runs as uid 1999 and cannot mkdir /var/cache/pipeline_root/user_defined_pipelines. Replace the named volume with a tmpfs mount (uid=1999,gid=1999,mode=0755) so the directory is writable by the pipeline-server process on startup. Pipeline root only holds ephemeral runtime pipeline state so tmpfs is correct. Verified: apm-dlstreamer container starts healthy, all 3 pipelines load. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- .env_pipeline-defect-detection: fix LLM_MODEL_NAME from bare 'Phi-4-mini-instruct' to full HF repo ID 'microsoft/Phi-4-mini-instruct' (bare name causes 401 RepositoryNotFoundError from HuggingFace Hub) - Add clear HUGGINGFACEHUB_API_TOKEN comment with instructions to accept model license before generating a token - setup.sh: skip compose.llm.yaml entirely when LLM_MODE=fallback so the VLM container is never started in rule-based mode (saves memory/GPU) - setup.sh: relax validation — LLM_MODEL_NAME/LLM_DEVICE are only required when LLM_MODE != fallback - Print active mode (LLM model+device or fallback) at startup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- pipeline-server-config.json: set auto_start=false for default CPU pipeline to avoid gst-resource-error at startup when sample.mp4 hasn't been downloaded yet. Pipeline server starts cleanly; pipeline is started via REST API once the video is available. - compose.base.yaml: expose DL Streamer REST port to host using PIPELINE_SERVER_PORT env var (default 8554); pass same value as REST_SERVER_PORT inside the container so host curl calls work. - setup.sh: after stack start, check if sample.mp4 exists and auto-start the DL Streamer pipeline via REST API (with 30s timeout waiting for Tornado server). If video is missing, print the prep command instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- setup.sh: rewrite stop_containers() to stop by fixed container names (apm-nginx, apm-ui, etc.) instead of 'docker compose down', which requires USE_CASE_* env vars to be set and fails when --down is called standalone. No env vars needed for teardown. - compose.agents.yaml: add ':-/tmp/apm-placeholder' defaults to USE_CASE_CONFIGS_DIR and USE_CASE_PROMPTS_DIR volume mounts so compose config parsing succeeds even when vars are unset (e.g. during --down). - compose.base.yaml: same fix for USE_CASE_CONFIGS_DIR volume mount on the dlstreamer-pipeline-server service. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When user runs 'LLM_MODE=fallback source setup.sh ...', the .env file was sourced after and overwrote LLM_MODE=fallback with LLM_MODE=llm, causing VLM to be started despite the fallback override. Fix: capture caller-supplied vars before sourcing the env file, restore them after. Currently preserves LLM_MODE; pattern can be extended to other override vars as needed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
proxy_pass http://agent_backend/ stripped '/api/agents/' from the path, sending '/runs' instead of '/agents/runs' to the agent service → 404. Fix: proxy_pass http://agent_backend/agents/ so /api/agents/runs maps correctly to /agents/runs on the agent service. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cv2.VideoWriter with mp4v codec writes the moov atom at the end of the file. GStreamer's qtdemux only scans the first 10 MB, causing: 'no moov atom within the first 10 MB' Run ffmpeg -movflags +faststart after cv2 writes the file to move moov to immediately after ftyp, making the file streamable from the start. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…download touchpoints, labels sync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Agent service:
- Fix MQTT subscriber to parse DL Streamer message format
(unwrap metadata.objects[] instead of treating payload as flat dict)
- Add DL Streamer watchdog (dlstreamer_client.py) that auto-starts and
restarts the pipeline when it completes
- Fix proxy bypass for all internal Docker service calls (storage, LLM,
DL Streamer) using trust_env=False / proxies={http:None}
- Add optional ?id= filter to GET /agents/runs
- Tune LLM max_tokens per agent: policy=512, analysis=800, evidence=600,
ticket=300 (was 2048 for all)
- Analysis agent: send compact deduplicated stats instead of 50 raw records
- Evidence agent: use summary + top-5 per class instead of fetching all records
- storage_client: add default limit=500 to prevent unbounded fetches
App config:
- pipeline-server-config.json: auto_start=true with MQTT payload destination
so CPU pipeline starts automatically on container start
- compose.agents.yaml: add DLSTREAMER_URL, DLSTREAMER_PIPELINE_NAME env vars
UI service:
- Fix empty min_confidence string causing 422 validation error
- Dashboard: auto-refresh when a run is in progress, active nav state
- Dashboard: move Clear Detections to detections page (Danger Zone)
- Detections: limit selector (50/100/250/500), show total count
- Results: per-agent status breakdown on error, Run Again button
- Run history: full run ID on hover (title attribute)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Please include a summary of the changes and the related issue. List any dependencies that are required for this change.
Fixes # (issue)
Any Newly Introduced Dependencies
Please describe any newly introduced 3rd party dependencies in this change. List their name, license information and how they are used in the project.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Checklist: