diff --git a/playbooks/core/comfyui-image-gen/playbook.json b/playbooks/core/comfyui-image-gen/playbook.json index f68b2a63..a99d368f 100644 --- a/playbooks/core/comfyui-image-gen/playbook.json +++ b/playbooks/core/comfyui-image-gen/playbook.json @@ -5,12 +5,24 @@ "time": 15, "unsupported_platforms": { "stx": [ - { "platform": "windows", "reason": "Z Image Turbo is too large for this device" }, - { "platform": "linux", "reason": "Z Image Turbo is too large for this device" } + { + "platform": "windows", + "reason": "Z Image Turbo is too large for this device" + }, + { + "platform": "linux", + "reason": "Z Image Turbo is too large for this device" + } ], "krk": [ - { "platform": "windows", "reason": "Z Image Turbo is too large for this device" }, - { "platform": "linux", "reason": "Z Image Turbo is too large for this device" } + { + "platform": "windows", + "reason": "Z Image Turbo is too large for this device" + }, + { + "platform": "linux", + "reason": "Z Image Turbo is too large for this device" + } ] }, "supported_platforms": { @@ -103,5 +115,13 @@ "comfyui", "z-image-turbo" ], - "coverImage": "assets/cover.jpeg" + "coverImage": "assets/cover.jpeg", + "minMemoryGB": 16, + "primaryModel": "Z-Image Turbo", + "validatedVersions": { + "reference": { + "windows": { "ComfyUI Desktop": "Latest from Ryzen AI Developer Center" }, + "linux": { "ComfyUI": "Latest from Ryzen AI Developer Center" } + } + } } diff --git a/playbooks/core/lmstudio-rocm-llms/playbook.json b/playbooks/core/lmstudio-rocm-llms/playbook.json index f9d83833..c21acd56 100644 --- a/playbooks/core/lmstudio-rocm-llms/playbook.json +++ b/playbooks/core/lmstudio-rocm-llms/playbook.json @@ -127,5 +127,7 @@ "llm", "inference" ], - "coverImage": "assets/cover_image.avif" + "coverImage": "assets/cover_image.avif", + "minMemoryGB": 8, + "primaryModel": "Qwen3.5-9B" } diff --git a/playbooks/core/n8n-automation-gpt-oss/playbook.json b/playbooks/core/n8n-automation-gpt-oss/playbook.json index db455199..9cd57785 100644 --- a/playbooks/core/n8n-automation-gpt-oss/playbook.json +++ b/playbooks/core/n8n-automation-gpt-oss/playbook.json @@ -127,5 +127,39 @@ "llm", "lemonade" ], - "coverImage": "assets/workflow-overview.png" + "coverImage": "assets/workflow-overview.png", + "minMemoryGB": 16, + "validatedVersions": { + "reference": { + "linux": { + "n8n": "2.33.5", + "Node.js": "22.22.1" + }, + "windows": { + "n8n": "2.33.5", + "Node.js": "22.22.1" + } + }, + "apu": { + "linux": { + "n8n": "Latest", + "Node.js": "22.22.1" + }, + "windows": { + "n8n": "Latest", + "Node.js": "22.22.1" + } + }, + "gpu": { + "linux": { + "n8n": "Latest", + "Node.js": "22.22.1" + }, + "windows": { + "n8n": "Latest", + "Node.js": "22.22.1" + } + } + }, + "primaryModel": "GPT-OSS-120B" } diff --git a/playbooks/core/pytorch-rocm-llms/playbook.json b/playbooks/core/pytorch-rocm-llms/playbook.json index 593966f0..63b22ed3 100644 --- a/playbooks/core/pytorch-rocm-llms/playbook.json +++ b/playbooks/core/pytorch-rocm-llms/playbook.json @@ -127,5 +127,13 @@ "inference", "summarization" ], - "coverImage": "assets/cover.png" + "coverImage": "assets/cover.png", + "minMemoryGB": 8, + "validatedVersions": { + "reference": { + "linux": {}, + "windows": {} + } + }, + "primaryModel": "Qwen3.5-4B" } diff --git a/playbooks/core/vscode-qwen3-coder/playbook.json b/playbooks/core/vscode-qwen3-coder/playbook.json index 6f03844c..5a143a99 100644 --- a/playbooks/core/vscode-qwen3-coder/playbook.json +++ b/playbooks/core/vscode-qwen3-coder/playbook.json @@ -126,5 +126,7 @@ "qwen", "llm" ], - "coverImage": "assets/open-cline-test.png" + "coverImage": "assets/open-cline-test.png", + "minMemoryGB": 24, + "primaryModel": "Qwen3-Coder-30B-A3B" } diff --git a/playbooks/dependencies/registry.json b/playbooks/dependencies/registry.json index 6b56fca9..f32fd35f 100644 --- a/playbooks/dependencies/registry.json +++ b/playbooks/dependencies/registry.json @@ -6,189 +6,296 @@ "name": "ComfyUI", "description": "Node-based Stable Diffusion interface", "category": "app", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "comfyui.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "pytorch": { "name": "PyTorch", "description": "Deep learning framework", "category": "framework", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "pytorch.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "lmstudio": { "name": "LM Studio", "description": "Desktop app for running local LLMs", "category": "app", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "lmstudio.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": true }, "vllm": { "name": "vLLM", "description": "High-throughput LLM serving engine", "category": "framework", - "platforms": ["linux"], + "platforms": [ + "linux" + ], "file": "vllm.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "n8n": { "name": "n8n", "description": "Workflow automation platform", "category": "app", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "n8n.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "vscode": { "name": "Visual Studio Code", "description": "Code editor with AI extensions", "category": "app", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "vscode.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": true }, "lemonade": { "name": "Lemonade", "description": "Local LLM server with OpenAI-compatible API", "category": "framework", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "lemonade.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "gaia": { "name": "GAIA", "description": "AMD framework for building AI agents on local hardware", "category": "framework", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "gaia.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": true }, "comfyui-models": { "name": "ComfyUI Models", "description": "ComfyUI models for image generation", "category": "model", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "comfyui_models.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": false }, "lmstudio-models-gpt-oss-120b": { "name": "GPT-OSS 120B Model", "description": "OpenAI GPT-OSS 120B model for LM Studio", "category": "model", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "lmstudio_models_gpt_oss_120b.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": false }, "lmstudio-models-qwen3-9b": { "name": "Qwen3.5 9B Model", "description": "Qwen3.5 9B model for LM Studio", "category": "model", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "lmstudio_models_qwen3_9b.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": false }, "driver": { "name": "AMD GPU Driver", "description": "Latest AMD GPU driver for optimal performance", "category": "driver", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "driver.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "nodejs": { "name": "Node.js", "version": "22.22.1", "description": "JavaScript runtime for server-side applications", "category": "runtime", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "nodejs.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "memory-config": { "name": "Memory Configuration", "description": "Configure GPU memory allocation for running large models", "category": "framework", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "memoryconfig.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": false }, "rocm": { "name": "ROCm", "description": "AMD software platform for GPU computing and AI workloads", "category": "framework", - "platforms": ["linux"], + "platforms": [ + "linux" + ], "file": "rocm.md", "preinstalled": { - "linux": ["halo_box"], - "windows": ["halo_box"] - } + "linux": [ + "halo_box" + ], + "windows": [ + "halo_box" + ] + }, + "versionable": true }, "podman": { "name": "Podman", "description": "Container management tool for running OCI containers", "category": "framework", - "platforms": ["linux"], + "platforms": [ + "linux" + ], "file": "podman.md", "preinstalled": { - "linux": ["halo_box"], + "linux": [ + "halo_box" + ], "windows": [] - } + }, + "versionable": true }, "software-update": { "name": "Software Updates", "description": "Check for and install software updates on the AMD Ryzen AI Halo", "category": "framework", - "platforms": ["windows", "linux"], + "platforms": [ + "windows", + "linux" + ], "file": "softwareupdate.md", "preinstalled": { "linux": [], "windows": [] - } + }, + "versionable": false } } } diff --git a/playbooks/dependency-versions.json b/playbooks/dependency-versions.json new file mode 100644 index 00000000..6e96cfb3 --- /dev/null +++ b/playbooks/dependency-versions.json @@ -0,0 +1,30 @@ +{ + "_comment": "Central version source for versionable dependencies (see 'versionable' flag in dependencies/registry.json). A playbook's shown software = its @require'd versionable deps (versions resolved here) + its own validatedVersions overrides in playbook.json (hero apps / pins). Structure per dep: a single string (same everywhere), OR an object with category keys (reference/apu/gpu) and/or 'default'. A category value is a string, or per-OS {linux,windows}. Resolution: category+OS -> category string -> 'default'. Apps installed from vendor/GitHub are pinned on reference (pre-installed, validated) and 'Latest' elsewhere (CI tests the current release). Empty string hides a row.", + "defaultDate": "2026-07", + "deps": { + "rocm": { + "reference": { "linux": "7.13.0", "windows": "7.13.0" }, + "apu": { "linux": "7.14.0", "windows": "7.14.0" }, + "gpu": { "linux": "7.14.0", "windows": "7.14.0" } + }, + "pytorch": { + "reference": { "linux": "2.11", "windows": "2.11" }, + "apu": { "linux": "2.12", "windows": "2.12" }, + "gpu": { "linux": "2.12", "windows": "2.12" } + }, + "driver": { + "reference": { "linux": "Latest from Ryzen AI Developer Center", "windows": "26.5.1 (from Ryzen AI Developer Center)" }, + "apu": { "linux": "Latest inbox driver", "windows": "Adrenalin 26.6.4" }, + "gpu": { "linux": "RSL 31.3.1", "windows": "Adrenalin 26.6.4" } + }, + "lemonade": { "reference": "10.5.1", "default": "Latest" }, + "lmstudio": { "reference": "Latest", "default": "Latest" }, + "n8n": { "reference": "Latest", "default": "Latest" }, + "vscode": { "reference": "1.130.0", "default": "Latest" }, + "gaia": { "reference": "0.22.0", "default": "Latest" }, + "comfyui": { "reference": "", "default": "Latest" }, + "vllm": { "reference": "0.21", "default": "Latest" }, + "nodejs": { "reference": "Latest", "default": "Latest" }, + "podman": { "reference": "", "default": "Latest" } + } +} diff --git a/playbooks/supplemental/amd-sync/playbook.json b/playbooks/supplemental/amd-sync/playbook.json index 2e533124..0e7ed97b 100644 --- a/playbooks/supplemental/amd-sync/playbook.json +++ b/playbooks/supplemental/amd-sync/playbook.json @@ -1,32 +1,68 @@ { "id": "amd-sync", "title": "Remote Development with AMD Sync", - "description": "Install AMD Sync on your laptop and get one-click remote VS Code, Terminal, JupyterLab, and Live Metrics on your AMD Ryzen\u2122 AI Halo.", + "description": "Install AMD Sync on your laptop and get one-click remote VS Code, Terminal, JupyterLab, and Live Metrics on your AMD Ryzen™ AI Halo.", "time": 15, "unsupported_platforms": { "halo": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ], "stx": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ], "krk": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ], "rx7900xt": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ], "rx9070xt": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ], "r9700": [ - { "platform": "windows", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" }, - { "platform": "linux", "reason": "AMD Sync is only supported on the AMD Ryzen\u2122 AI Halo Developer Platform" } + { + "platform": "windows", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + }, + { + "platform": "linux", + "reason": "AMD Sync is only supported on the AMD Ryzen™ AI Halo Developer Platform" + } ] }, "supported_platforms": { @@ -53,5 +89,15 @@ "vscode", "jupyterlab", "halo_box" - ] + ], + "validatedVersions": { + "reference": { + "linux": { + "AMD Sync": "1.0" + }, + "windows": { + "AMD Sync": "1.0" + } + } + } } diff --git a/playbooks/supplemental/clustering-rccl/playbook.json b/playbooks/supplemental/clustering-rccl/playbook.json index 88ce714b..970ca008 100644 --- a/playbooks/supplemental/clustering-rccl/playbook.json +++ b/playbooks/supplemental/clustering-rccl/playbook.json @@ -1,34 +1,70 @@ { "id": "clustering-rccl", "title": "Clustering Two Ryzen™ AI Halos with RCCL", - "description": "Set up a multi-node cluster using two Ryzen\u2122 AI Halo devices with RCCL for distributed workloads", + "description": "Set up a multi-node cluster using two Ryzen™ AI Halo devices with RCCL for distributed workloads", "time": 90, "unsupported_platforms": { "halo_box": [ - { "platform": "windows", "reason": "RCCL clustering relies on vLLM which is only supported on Linux" } + { + "platform": "windows", + "reason": "RCCL clustering relies on vLLM which is only supported on Linux" + } ], "halo": [ - { "platform": "windows", "reason": "RCCL clustering relies on vLLM which is only supported on Linux" } + { + "platform": "windows", + "reason": "RCCL clustering relies on vLLM which is only supported on Linux" + } ], "stx": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "krk": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "rx7900xt": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "rx9070xt": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "r9700": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ] }, "supported_platforms": { @@ -41,7 +77,7 @@ }, "published_platforms": { "halo_box": [ - "linux" + "linux" ], "halo": [ "linux" @@ -58,5 +94,19 @@ "multi-gpu", "rccl", "vllm" - ] + ], + "minMemoryGB": 128, + "validatedVersions": { + "reference": { + "linux": { + "vLLM": "Latest from Ryzen AI Developer Center" + } + }, + "apu": { + "linux": { + "vLLM": "Latest" + } + } + }, + "primaryModel": "Qwen3.5-397B-A17B" } diff --git a/playbooks/supplemental/clustering-rpc-server/playbook.json b/playbooks/supplemental/clustering-rpc-server/playbook.json index 454ca962..f294ad93 100644 --- a/playbooks/supplemental/clustering-rpc-server/playbook.json +++ b/playbooks/supplemental/clustering-rpc-server/playbook.json @@ -1,28 +1,58 @@ { "id": "clustering-rpc-server", "title": "Clustering Two Ryzen™ AI Halos with RPC", - "description": "Set up distributed inference using RPC server across two Ryzen\u2122 AI Halo devices with llama.cpp to run 350B+ models", + "description": "Set up distributed inference using RPC server across two Ryzen™ AI Halo devices with llama.cpp to run 350B+ models", "time": 90, "unsupported_platforms": { "stx": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "krk": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "rx7900xt": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "rx9070xt": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ], "r9700": [ - { "platform": "windows", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" }, - { "platform": "linux", "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" } + { + "platform": "windows", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + }, + { + "platform": "linux", + "reason": "This clustering playbook requires 2+ Strix Halo systems with large memory capacity" + } ] }, "supported_platforms": { @@ -57,5 +87,22 @@ "llm", "inference", "rocm" - ] + ], + "minMemoryGB": 128, + "validatedVersions": { + "reference": { + "linux": { + "llama.cpp": "Latest" + } + }, + "apu": { + "linux": { + "llama.cpp": "Latest" + }, + "windows": { + "llama.cpp": "Latest" + } + } + }, + "primaryModel": "GLM-4.7" } diff --git a/playbooks/supplemental/cvml/playbook.json b/playbooks/supplemental/cvml/playbook.json index fbe17aae..230f2758 100644 --- a/playbooks/supplemental/cvml/playbook.json +++ b/playbooks/supplemental/cvml/playbook.json @@ -1,17 +1,20 @@ { "id": "cvml", - "title": "Local Computer Vision with AMD Ryzen\u2122 AI NPU", - "description": "Build local perception capabilities using the CVML SDK on top of Ryzen AI and AMD ROCm\u2122 software", + "title": "Local Computer Vision with AMD Ryzen™ AI NPU", + "description": "Build local perception capabilities using the CVML SDK on top of Ryzen AI and AMD ROCm™ software", "time": 45, "unsupported_platforms": { "halo_box": [ - { "platform": "linux", "reason": "CVML support on Debian OS is planned for the ROCm 7.14 release" } + { + "platform": "linux", + "reason": "CVML support on Debian OS is planned for the ROCm 7.14 release" + } ] }, "supported_platforms": { "halo_box": [ "windows" - ], + ], "halo": [ "linux", "windows" @@ -82,5 +85,23 @@ "gpu", "npu", "inference" - ] + ], + "validatedVersions": { + "reference": { + "linux": { + "CVML": "Latest" + }, + "windows": { + "CVML": "Latest" + } + }, + "apu": { + "linux": { + "CVML": "Latest" + }, + "windows": { + "CVML": "Latest" + } + } + } } diff --git a/playbooks/supplemental/deepseek-v4-flash-ds4/playbook.json b/playbooks/supplemental/deepseek-v4-flash-ds4/playbook.json index 02ad4c6e..81b90d6e 100644 --- a/playbooks/supplemental/deepseek-v4-flash-ds4/playbook.json +++ b/playbooks/supplemental/deepseek-v4-flash-ds4/playbook.json @@ -40,5 +40,19 @@ "rocm", "llm", "inference" - ] + ], + "minMemoryGB": 128, + "validatedVersions": { + "reference": { + "linux": { + "ds4": "Latest" + } + }, + "apu": { + "linux": { + "ds4": "Latest" + } + } + }, + "primaryModel": "DeepSeek V4 Flash (IQ2_XXS)" } diff --git a/playbooks/supplemental/gaia-agents/playbook.json b/playbooks/supplemental/gaia-agents/playbook.json index bb422e5d..62826dd4 100644 --- a/playbooks/supplemental/gaia-agents/playbook.json +++ b/playbooks/supplemental/gaia-agents/playbook.json @@ -1,7 +1,7 @@ { "id": "gaia-agents", "title": "Building Your First Agent with GAIA", - "description": "Build a 100% local AI agent \u2014 no cloud APIs needed. Use the GAIA SDK to create a hardware advisor.", + "description": "Build a 100% local AI agent — no cloud APIs needed. Use the GAIA SDK to create a hardware advisor.", "time": 15, "supported_platforms": { "halo_box": [ @@ -127,5 +127,7 @@ "hardware", "lemonade" ], - "coverImage": "assets/gaia.jpg" + "coverImage": "assets/gaia.jpg", + "minMemoryGB": 8, + "primaryModel": "Qwen3-0.6B" } diff --git a/playbooks/supplemental/github-slack-development-digest/playbook.json b/playbooks/supplemental/github-slack-development-digest/playbook.json index 596ac49a..e1173b8e 100644 --- a/playbooks/supplemental/github-slack-development-digest/playbook.json +++ b/playbooks/supplemental/github-slack-development-digest/playbook.json @@ -35,5 +35,22 @@ "lemonade", "llm" ], - "coverImage": "assets/00-architecture-overview.png" + "coverImage": "assets/00-architecture-overview.png", + "minMemoryGB": 32, + "validatedVersions": { + "reference": { + "linux": { + "Agent Canvas": "1.10.0" + } + }, + "apu": { + "linux": { + "Agent Canvas": "Latest" + }, + "windows": { + "Agent Canvas": "Latest" + } + } + }, + "primaryModel": "Qwen3.6-35B-A3B" } diff --git a/playbooks/supplemental/hermes-lemonade-server/playbook.json b/playbooks/supplemental/hermes-lemonade-server/playbook.json index f5ac45a7..f58f118d 100644 --- a/playbooks/supplemental/hermes-lemonade-server/playbook.json +++ b/playbooks/supplemental/hermes-lemonade-server/playbook.json @@ -127,5 +127,33 @@ "local-ai", "docker", "linux" - ] + ], + "minMemoryGB": 32, + "validatedVersions": { + "reference": { + "linux": { + "Hermes": "0.20.0" + }, + "windows": { + "Hermes": "0.20.0" + } + }, + "apu": { + "linux": { + "Hermes": "Latest" + }, + "windows": { + "Hermes": "Latest" + } + }, + "gpu": { + "linux": { + "Hermes": "Latest" + }, + "windows": { + "Hermes": "Latest" + } + } + }, + "primaryModel": "Qwen3.6-35B-A3B" } diff --git a/playbooks/supplemental/lemonade-getting-started/playbook.json b/playbooks/supplemental/lemonade-getting-started/playbook.json index 5b828be5..4d119764 100644 --- a/playbooks/supplemental/lemonade-getting-started/playbook.json +++ b/playbooks/supplemental/lemonade-getting-started/playbook.json @@ -127,5 +127,7 @@ "npu", "inference" ], - "coverImage": "../../dependencies/assets/multi_modality.png" + "coverImage": "../../dependencies/assets/multi_modality.png", + "minMemoryGB": 8, + "primaryModel": "Gemma-4-E2B-it" } diff --git a/playbooks/supplemental/llama-factory-finetuning/playbook.json b/playbooks/supplemental/llama-factory-finetuning/playbook.json index eeff1fab..8e69e6f1 100644 --- a/playbooks/supplemental/llama-factory-finetuning/playbook.json +++ b/playbooks/supplemental/llama-factory-finetuning/playbook.json @@ -115,12 +115,44 @@ "windows" ] }, - "platforms": ["linux", "windows"], + "platforms": [ + "linux", + "windows" + ], "difficulty": "intermediate", "isNew": false, "isFeatured": false, "developed": true, "published": true, - "tags": ["Llama Factory", "lora", "fine-tuning"], - "coverImage": "assets/cover.png" + "tags": [ + "Llama Factory", + "lora", + "fine-tuning" + ], + "coverImage": "assets/cover.png", + "minMemoryGB": 16, + "validatedVersions": { + "reference": { + "linux": { + "LLaMA-Factory": "Latest" + } + }, + "apu": { + "linux": { + "LLaMA-Factory": "Latest" + }, + "windows": { + "LLaMA-Factory": "Latest" + } + }, + "gpu": { + "linux": { + "LLaMA-Factory": "Latest" + }, + "windows": { + "LLaMA-Factory": "Latest" + } + } + }, + "primaryModel": "Qwen3-4B-Instruct" } diff --git a/playbooks/supplemental/ollama-getting-started/playbook.json b/playbooks/supplemental/ollama-getting-started/playbook.json index 2c9403d5..2deb94cf 100644 --- a/playbooks/supplemental/ollama-getting-started/playbook.json +++ b/playbooks/supplemental/ollama-getting-started/playbook.json @@ -1,7 +1,7 @@ { "id": "ollama-getting-started", "title": "Getting Started with Ollama", - "description": "Install Ollama and run LLMs locally \u2014 chat from the terminal, desktop app, or REST API.", + "description": "Install Ollama and run LLMs locally — chat from the terminal, desktop app, or REST API.", "time": 15, "supported_platforms": { "halo_box": [ @@ -127,5 +127,33 @@ "local", "api" ], - "coverImage": "assets/ollama_app.png" + "coverImage": "assets/ollama_app.png", + "minMemoryGB": 16, + "validatedVersions": { + "reference": { + "linux": { + "Ollama": "0.32.6" + }, + "windows": { + "Ollama": "0.32.6" + } + }, + "apu": { + "linux": { + "Ollama": "Latest" + }, + "windows": { + "Ollama": "Latest" + } + }, + "gpu": { + "linux": { + "Ollama": "Latest" + }, + "windows": { + "Ollama": "Latest" + } + } + }, + "primaryModel": "GPT-OSS-20B" } diff --git a/playbooks/supplemental/open-webui-chat/playbook.json b/playbooks/supplemental/open-webui-chat/playbook.json index e5142420..9666bbc4 100644 --- a/playbooks/supplemental/open-webui-chat/playbook.json +++ b/playbooks/supplemental/open-webui-chat/playbook.json @@ -114,7 +114,7 @@ "linux", "windows" ] - }, + }, "difficulty": "beginner", "isNew": false, "isFeatured": false, @@ -128,5 +128,33 @@ "vlm", "stable-diffusion" ], - "coverImage": "assets/open-webui_chat_interface.png" + "coverImage": "assets/open-webui_chat_interface.png", + "minMemoryGB": 8, + "validatedVersions": { + "reference": { + "linux": { + "Open WebUI": "0.11" + }, + "windows": { + "Open WebUI": "0.11" + } + }, + "apu": { + "linux": { + "Open WebUI": "Latest" + }, + "windows": { + "Open WebUI": "Latest" + } + }, + "gpu": { + "linux": { + "Open WebUI": "Latest" + }, + "windows": { + "Open WebUI": "Latest" + } + } + }, + "primaryModel": "Qwen3-4B" } diff --git a/playbooks/supplemental/openclaw-lemonade-server/playbook.json b/playbooks/supplemental/openclaw-lemonade-server/playbook.json index 35cfa491..214684ec 100644 --- a/playbooks/supplemental/openclaw-lemonade-server/playbook.json +++ b/playbooks/supplemental/openclaw-lemonade-server/playbook.json @@ -126,5 +126,30 @@ "agent", "local-ai", "linux" - ] + ], + "minMemoryGB": 32, + "validatedVersions": { + "reference": { + "linux": { + "OpenClaw": "2026.7.1-2" + } + }, + "apu": { + "linux": { + "OpenClaw": "Latest" + }, + "windows": { + "OpenClaw": "Latest" + } + }, + "gpu": { + "linux": { + "OpenClaw": "Latest" + }, + "windows": { + "OpenClaw": "Latest" + } + } + }, + "primaryModel": "Qwen3.6-35B-A3B" } diff --git a/playbooks/supplemental/openhands-getting-started/playbook.json b/playbooks/supplemental/openhands-getting-started/playbook.json index 1ebc6789..35c074fa 100644 --- a/playbooks/supplemental/openhands-getting-started/playbook.json +++ b/playbooks/supplemental/openhands-getting-started/playbook.json @@ -1,7 +1,7 @@ { "id": "openhands-getting-started", "title": "Getting Started with OpenHands and a Local LLM", - "description": "Install Agent Canvas, connect a local Lemonade model, and run your first OpenHands coding agent on your AMD Ryzen\u2122 AI.", + "description": "Install Agent Canvas, connect a local Lemonade model, and run your first OpenHands coding agent on your AMD Ryzen™ AI.", "time": 20, "supported_platforms": { "halo_box": [ @@ -45,5 +45,33 @@ "lemonade", "llm" ], - "coverImage": "assets/02-agent-canvas-home.png" + "coverImage": "assets/02-agent-canvas-home.png", + "minMemoryGB": 32, + "validatedVersions": { + "reference": { + "linux": { + "Agent Canvas": "1.10.0" + }, + "windows": { + "Agent Canvas": "1.10.0" + } + }, + "apu": { + "linux": { + "Agent Canvas": "Latest" + }, + "windows": { + "Agent Canvas": "Latest" + } + }, + "gpu": { + "linux": { + "Agent Canvas": "Latest" + }, + "windows": { + "Agent Canvas": "Latest" + } + } + }, + "primaryModel": "Qwen3.6-35B-A3B" } diff --git a/playbooks/supplemental/pytorch-finetuning/playbook.json b/playbooks/supplemental/pytorch-finetuning/playbook.json index 8da48f93..513bc913 100644 --- a/playbooks/supplemental/pytorch-finetuning/playbook.json +++ b/playbooks/supplemental/pytorch-finetuning/playbook.json @@ -126,5 +126,13 @@ "llm", "rocm" ], - "coverImage": "assets/cover_image.jpg" + "coverImage": "assets/cover_image.jpg", + "minMemoryGB": 16, + "validatedVersions": { + "reference": { + "linux": {}, + "windows": {} + } + }, + "primaryModel": "Gemma-3-4B" } diff --git a/playbooks/supplemental/pytorch-kernels/playbook.json b/playbooks/supplemental/pytorch-kernels/playbook.json index 74188af8..1fbfeb6d 100644 --- a/playbooks/supplemental/pytorch-kernels/playbook.json +++ b/playbooks/supplemental/pytorch-kernels/playbook.json @@ -1,7 +1,7 @@ { "id": "pytorch-kernels", - "title": "Building Custom GPU Kernels with PyTorch and AMD ROCm\u2122", - "description": "Write and optimize custom GPU kernels using PyTorch and AMD ROCm\u2122 software", + "title": "Building Custom GPU Kernels with PyTorch and AMD ROCm™", + "description": "Write and optimize custom GPU kernels using PyTorch and AMD ROCm™ software", "time": 60, "supported_platforms": { "halo_box": [ @@ -127,5 +127,11 @@ "kernels", "optimization" ], - "coverImage": "assets/cover.png" + "coverImage": "assets/cover.png", + "validatedVersions": { + "reference": { + "linux": {}, + "windows": {} + } + } } diff --git a/playbooks/supplemental/speech2speech-translation/playbook.json b/playbooks/supplemental/speech2speech-translation/playbook.json index b7299b5a..89db12f6 100644 --- a/playbooks/supplemental/speech2speech-translation/playbook.json +++ b/playbooks/supplemental/speech2speech-translation/playbook.json @@ -126,5 +126,12 @@ "audio", "real-time" ], - "coverImage": "assets/gradio.png" + "coverImage": "assets/gradio.png", + "minMemoryGB": 8, + "validatedVersions": { + "reference": { + "linux": {} + } + }, + "primaryModel": "SeamlessM4T v2 Large" } diff --git a/playbooks/supplemental/unsloth-llms-finetuning/playbook.json b/playbooks/supplemental/unsloth-llms-finetuning/playbook.json index cae67b9e..daafe60e 100644 --- a/playbooks/supplemental/unsloth-llms-finetuning/playbook.json +++ b/playbooks/supplemental/unsloth-llms-finetuning/playbook.json @@ -118,6 +118,36 @@ "isFeatured": false, "developed": true, "published": true, - "tags": ["unsloth", "sft", "fine-tuning", "optimization"], - "coverImage": "assets/unsloth.png" + "tags": [ + "unsloth", + "sft", + "fine-tuning", + "optimization" + ], + "coverImage": "assets/unsloth.png", + "minMemoryGB": 16, + "validatedVersions": { + "reference": { + "linux": { + "Unsloth": "0.1.524" + } + }, + "apu": { + "linux": { + "Unsloth": "Latest" + }, + "windows": { + "Unsloth": "Latest" + } + }, + "gpu": { + "linux": { + "Unsloth": "Latest" + }, + "windows": { + "Unsloth": "Latest" + } + } + }, + "primaryModel": "Gemma-4-E4B-it" } diff --git a/playbooks/supplemental/vllm-inference/playbook.json b/playbooks/supplemental/vllm-inference/playbook.json index dde30850..ee413fca 100644 --- a/playbooks/supplemental/vllm-inference/playbook.json +++ b/playbooks/supplemental/vllm-inference/playbook.json @@ -5,25 +5,46 @@ "time": 30, "unsupported_platforms": { "halo_box": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "halo": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "stx": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "krk": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "rx7900xt": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "rx9070xt": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ], "r9700": [ - { "platform": "windows", "reason": "vLLM is not supported on Windows" } + { + "platform": "windows", + "reason": "vLLM is not supported on Windows" + } ] }, "supported_platforms": { @@ -46,5 +67,14 @@ "inference", "llm", "quickstart" - ] + ], + "minMemoryGB": 8, + "validatedVersions": { + "reference": { + "linux": { + "vLLM": "Latest from Ryzen AI Developer Center" + } + } + }, + "primaryModel": "Qwen3-1.7B" } diff --git a/website/src/app/api/playbooks/[id]/route.ts b/website/src/app/api/playbooks/[id]/route.ts index e09d1558..01231426 100644 --- a/website/src/app/api/playbooks/[id]/route.ts +++ b/website/src/app/api/playbooks/[id]/route.ts @@ -5,7 +5,8 @@ import { NextResponse } from "next/server"; import fs from "fs"; import path from "path"; -import type { Playbook, PlaybookMeta, Category, TestInfo, TestCoverageInfo } from "@/types/playbook"; +import type { Playbook, PlaybookMeta, Category, TestInfo, TestCoverageInfo, Device, Platform, ValidationInfo, DeviceCategory } from "@/types/playbook"; +import { categoryForDevice } from "@/types/playbook"; import { loadAllGitHubTestResults } from "@/lib/github-test-results"; import type { DeviceTestResult } from "@/lib/github-test-results"; @@ -22,6 +23,7 @@ interface DependencyRegistry { platforms: string[]; file: string; preinstalled?: Record; + versionable?: boolean; }>; setup?: Record; + +// A dependency version entry is either a single string (same everywhere) or +// keyed by device category (reference/apu/gpu) then OS. +type DepVersionEntry = + | string + | ({ default?: string } & Partial>>>); + +interface DepVersionsFile { + defaultDate?: string; + deps?: Record; +} + +/** + * Loads the central dependency-version file (playbooks/dependency-versions.json). + */ +function loadDepVersions(): DepVersionsFile | null { + const p = path.join(PLAYBOOKS_ROOT, "dependency-versions.json"); + if (!fs.existsSync(p)) return null; + try { + return JSON.parse(fs.readFileSync(p, "utf-8")); + } catch (error) { + console.error("Error loading dependency-versions.json:", error); + return null; + } +} + +function resolveDepVersion(entry: DepVersionEntry | undefined, cat: DeviceCategory, os: Platform): string | undefined { + if (entry == null) return undefined; + if (typeof entry === "string") return entry; + // A category value may be a plain string (same for both OSes) or per-OS. + // Falls back to the entry's "default" (e.g. "Latest" for non-reference devices + // where CI tests the current release rather than a pinned pre-installed version). + const catVal = entry[cat]; + if (typeof catVal === "string") return catVal; + if (catVal && catVal[os] != null) return catVal[os]; + return typeof entry.default === "string" ? entry.default : undefined; +} + +/** + * Builds the resolved per-device, per-OS "validated versions" map for a playbook. + * + * The software shown for a device+OS is the union of: + * 1. the playbook's @require'd dependencies that are marked versionable in + * dependencies/registry.json, with versions resolved from the central + * dependency-versions.json for that device category + OS; and + * 2. the playbook's own validatedVersions overrides in playbook.json (hero + * apps not captured by @require, or version pins) which win on same-named keys. + * + * This means a playbook only lists software it actually uses — e.g. a Lemonade + * playbook shows Lemonade + driver, not ROCm/PyTorch, unless it @requires them. + * Empty-string versions hide that row. Returns undefined if there is nothing to show. + */ +// Strips the OS blocks that don't match `platform`, so @require tags can be +// read per-OS (e.g. ComfyUI requires pytorch on Linux but not Windows, where it +// ships bundled). Mirrors the content OS-filter used for rendering. +function requiresForOS(readmeRaw: string, platform: Platform, registry: DependencyRegistry | null): string[] { + const other: Platform = platform === "windows" ? "linux" : "windows"; + // Remove blocks scoped to the other OS; keep @os:all and unscoped content. + const scoped = readmeRaw.replace( + new RegExp(`[\\s\\S]*?`, "g"), + "", + ); + const ids = new Set(); + const reqRe = //g; + let m: RegExpExecArray | null; + while ((m = reqRe.exec(scoped)) !== null) { + for (const id of m[1].split(",").map(s => s.trim()).filter(Boolean)) ids.add(id); + } + return [...ids].filter(id => registry?.dependencies[id]?.versionable); +} + +function buildValidation(meta: PlaybookMeta, readmeRaw: string): PlaybookMeta["validation"] | undefined { + const overrides = meta.validatedVersions; + const registry = loadDependencyRegistry(); + + // Quick opt-in check: any versionable require anywhere, or any override. + const anyReq = //g; + let hasVersionableReq = false; + let mm: RegExpExecArray | null; + while ((mm = anyReq.exec(readmeRaw)) !== null) { + if (mm[1].split(",").some(id => registry?.dependencies[id.trim()]?.versionable)) { hasVersionableReq = true; break; } + } + if (!hasVersionableReq && !overrides) return undefined; + + const depFile = loadDepVersions(); + const deps = depFile?.deps ?? {}; + const date = meta.validatedDate ?? depFile?.defaultDate; + + const result: Partial>>> = {}; + + for (const [device, platforms] of Object.entries(meta.supported_platforms) as [Device, Platform[]][]) { + if (!platforms) continue; + const category = categoryForDevice(device); + + const perPlatform: Partial> = {}; + for (const platform of platforms) { + const versions: VersionMap = {}; + // 1. required versionable deps for THIS OS, versions from the central file + for (const id of requiresForOS(readmeRaw, platform, registry)) { + const name = registry?.dependencies[id]?.name ?? id; + const v = resolveDepVersion(deps[id], category, platform); + if (v !== undefined) versions[name] = v; + } + // 2. playbook overrides (hero apps / pins) win on same-named keys + Object.assign(versions, overrides?.[category]?.[platform] ?? {}); + // hide blank rows + const filtered: VersionMap = {}; + for (const [k, v] of Object.entries(versions)) { + if (v && v.trim() !== "") filtered[k] = v; + } + if (Object.keys(filtered).length > 0) { + perPlatform[platform] = { lastValidated: date, versions: filtered }; + } + } + + if (Object.keys(perPlatform).length > 0) { + result[device] = perPlatform; + } + } + + return Object.keys(result).length > 0 ? result : undefined; +} + /** * Loads a dependency's markdown content */ @@ -456,9 +582,11 @@ function findPlaybook( if (meta.id === id) { let content = ""; + let readmeRaw = ""; let testCoverage: TestCoverageInfo | undefined; if (fs.existsSync(readmePath)) { content = fs.readFileSync(readmePath, "utf-8"); + readmeRaw = content; content = stripGitHubOnlyBlocks(content); const testResult = processTestTags(content, showCoverage, resultsMap, resultsSummary, deviceResultsList, deviceSummaries); content = testResult.content; @@ -477,14 +605,20 @@ function findPlaybook( content = processSetupTags(content); } + // Validated versions are resolved at request time: the playbook's + // @require'd versionable deps (versions from playbooks/dependency-versions.json) + // plus the playbook's own validatedVersions overrides. + const validation = buildValidation(meta, readmeRaw); + const playbook: Playbook = { ...meta, category: getCategory(category), path: `${category}/${folder.name}`, content, + ...(validation ? { validation } : {}), ...(testCoverage ? { testCoverage } : {}), }; - + return playbook; } } catch (error) { diff --git a/website/src/app/playbooks/[id]/page.tsx b/website/src/app/playbooks/[id]/page.tsx index 9d37e853..0448c56b 100644 --- a/website/src/app/playbooks/[id]/page.tsx +++ b/website/src/app/playbooks/[id]/page.tsx @@ -21,7 +21,7 @@ import ImageLightbox from "@/components/ImageLightbox"; import CodeLightbox from "@/components/CodeLightbox"; import PlaybookHelpBox from "@/components/PlaybookHelpBox"; import type { Playbook, Platform, Device, DeviceCategory, TestCoverageInfo, TestResultInfo } from "@/types/playbook"; -import { formatTime, DEVICE_IDS, deviceNames, extractPlatforms, extractDevices, extractCategories, extractCategoryDevices, DEVICE_CATEGORY_MAP, categoryForDevice } from "@/types/playbook"; +import { formatTime, formatValidationDate, DEVICE_IDS, deviceNames, extractPlatforms, extractDevices, extractCategories, extractCategoryDevices, DEVICE_CATEGORY_MAP, categoryForDevice } from "@/types/playbook"; // Global store for dropdown states - persists across re-renders without causing them const dropdownStateStore: Record = {}; @@ -2188,6 +2188,69 @@ export default function PlaybookPage({ params, searchParams }: { params: Promise )} + {/* Validation info — versions/date this playbook was last validated with. + Kept separate from the README content; changes with the device/OS toggle. */} + {filteredContent && !coverageViewActive && (() => { + const info = + selectedDevice + ? playbook.validation?.[selectedDevice]?.[selectedPlatform] + : undefined; + const versionEntries = info?.versions + ? Object.entries(info.versions).filter(([, v]) => v && v.trim() !== "") + : []; + const validatedDate = formatValidationDate(info?.lastValidated); + if (versionEntries.length === 0 && !validatedDate) return null; + const deviceLabel = selectedDevice ? deviceNames[selectedDevice] : ""; + const osLabel = selectedPlatform === "windows" ? "Windows" : "Linux"; + return ( +
+
+
+ + + +

Validation

+
+ {validatedDate && ( + + Last validated {validatedDate} + + )} +
+

+ Software versions this playbook was verified with on{" "} + {deviceLabel} ({osLabel}). +

+ {versionEntries.length > 0 ? ( +
+ + + {versionEntries.map(([key, value], idx) => ( + + + + + ))} + +
+ {key} + + {value} +
+
+ ) : ( +

+ Version details for this configuration are being finalized. +

+ )} +
+ ); + })()} + + {/* Need help? — links to GitHub issues */} {filteredContent && ( diff --git a/website/src/types/playbook.ts b/website/src/types/playbook.ts index 00257c6d..d692d4a0 100644 --- a/website/src/types/playbook.ts +++ b/website/src/types/playbook.ts @@ -194,6 +194,53 @@ export interface PlaybookMeta { /** Cover image path relative to the playbook folder (e.g., "assets/cover.png") */ coverImage?: string; + + /** + * The main / default model this playbook runs, for at-a-glance user clarity. + * A single representative name even when the playbook mentions several + * (show the recommended/default one). Omitted for playbooks with no model + * (e.g. dev tools like AMD Sync, CVML, the kernel tutorial). + * Example: "primaryModel": "Qwen3.6-35B-A3B" + */ + primaryModel?: string; + + /** + * Minimum GPU memory (in GB) recommended to run this playbook, based on the + * smallest model it uses. A single number; the frontend adds any OS-specific + * wording (e.g. shared GPU memory pool on Linux vs. dedicated GPU memory on + * Windows). Users with less memory should pick a smaller model where the + * playbook supports it. Example: "minMemoryGB": 16 + */ + minMemoryGB?: number; + + /** + * Per-playbook software-version overrides, keyed by device CATEGORY + * (reference / apu / gpu) then OS. Use for the playbook's hero app that isn't + * captured by an @require tag (e.g. ds4, llama.cpp, the model) or to pin a + * version different from the central value. Required, versionable deps + * (@require tags) get their versions from playbooks/dependency-versions.json; + * these overrides win on same-named keys. Example: + * "validatedVersions": { + * "reference": { "windows": { "ComfyUI": "0.5.4", "PyTorch": "2.10" } } + * } + */ + validatedVersions?: Partial>>>>; + + /** Month/year this playbook was validated, e.g. "2026-07". Falls back to dependency-versions.json defaultDate. */ + validatedDate?: string; + + /** + * Resolved per-device, per-OS validation shown at the bottom of the playbook. + * Populated server-side (baseline + validatedVersions merged); not authored by hand. + */ + validation?: Partial>>>; +} + +export interface ValidationInfo { + /** Month/year the playbook was last validated, e.g. "2026-07" (rendered as "July 2026") */ + lastValidated?: string; + /** Key/value pairs of software validated for this device+OS, e.g. { "ROCm": "7.13.0" } */ + versions?: Record; } export interface TestResultInfo { @@ -260,6 +307,24 @@ export interface Playbook extends PlaybookMeta { testCoverage?: TestCoverageInfo; } +/** + * Formats a "YYYY-MM" or "YYYY-MM-DD" validation date into a human-readable + * string like "July 2026". Falls back to the raw string if it can't be parsed. + */ +export function formatValidationDate(value?: string): string { + if (!value) return ""; + const match = /^(\d{4})-(\d{2})/.exec(value.trim()); + if (!match) return value; + const year = Number(match[1]); + const monthIndex = Number(match[2]) - 1; + const months = [ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December", + ]; + if (monthIndex < 0 || monthIndex > 11) return value; + return `${months[monthIndex]} ${year}`; +} + /** * Formats time in minutes to a human-readable string */