项目文件夹

文件
wehub-resource-sync 9e8f1bbeed
Dashboard / frontend (push) Failing after 0s
Dashboard / api (push) Failing after 0s
Lint PowerShell / powershell-lint (ubuntu-latest) (push) Failing after 1s
Python Lint / Lint Python with Ruff (push) Failing after 1s
ShellCheck / Lint shell scripts (push) Failing after 1s
Matrix Smoke / linux-smoke (push) Failing after 1s
Matrix Smoke / distro: cachyos (push) Failing after 15s
Matrix Smoke / distro: linux-mint-21.3 (push) Failing after 15s
Matrix Smoke / distro: debian-12 (push) Failing after 5m21s
Matrix Smoke / distro: fedora-41 (push) Failing after 4m56s
Matrix Smoke / distro: ubuntu-24.04 (push) Failing after 2m13s
Matrix Smoke / distro: rocky-9 (push) Failing after 10m39s
Matrix Smoke / distro: manjaro (push) Failing after 12m11s
Matrix Smoke / distro: opensuse-tw (push) Failing after 11m53s
Matrix Smoke / distro: archlinux (push) Failing after 20m3s
Matrix Smoke / distro: ubuntu-22.04 (push) Failing after 13m49s
Validate .env Schema / tier-1-env-validation (push) Successful in 52s
Validate .env Schema / tier-2-env-validation (push) Successful in 44s
Validate .env Schema / tier-3-env-validation (push) Successful in 52s
Validate .env Schema / tier-4-env-validation (push) Successful in 51s
Validate Extensions Catalog / Check catalog is up-to-date (push) Failing after 9m47s
Secret Scan / Scan for secrets (push) Failing after 21m4s
Validate Docker Compose / Validate Docker Compose files (push) Has been cancelled
Python Type Check / Type check with mypy (push) Has been cancelled
Validate .env Schema / tier-0-env-validation (push) Has been cancelled
Test Linux / integration-smoke (push) Has been cancelled
Lint PowerShell / powershell-lint (windows-latest) (push) Has been cancelled
Matrix Smoke / macos-smoke (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:33 +08:00

303 行
9.3 KiB
Bash
可执行文件

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
#!/bin/bash
# ODS First Boot Demo
# Shows off what your local AI stack can do in under 2 minutes
#
# Usage: ./first-boot-demo.sh [--all] [--quick]
# Mission: M5 (Clonable ODS Setup Server)
set -euo pipefail
#=============================================================================
# Colors
#=============================================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m'
BOLD='\033[1m'
#=============================================================================
# Config — resolve from service registry when available
#=============================================================================
_DEMO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
if [[ -f "$_DEMO_DIR/lib/service-registry.sh" ]]; then
export SCRIPT_DIR="$_DEMO_DIR"
. "$_DEMO_DIR/lib/service-registry.sh"
sr_load
[[ -f "$_DEMO_DIR/lib/safe-env.sh" ]] && . "$_DEMO_DIR/lib/safe-env.sh"
load_env_file "$_DEMO_DIR/.env"
sr_resolve_ports
fi
LLM_URL="${LLM_URL:-http://localhost:${SERVICE_PORTS[llama-server]:-11434}}"
WHISPER_URL="${WHISPER_URL:-http://localhost:${SERVICE_PORTS[whisper]:-9000}}"
PIPER_URL="${PIPER_URL:-http://localhost:${SERVICE_PORTS[tts]:-8880}}"
N8N_URL="${N8N_URL:-http://localhost:${SERVICE_PORTS[n8n]:-5678}}"
WEBUI_URL="${WEBUI_URL:-http://localhost:${SERVICE_PORTS[open-webui]:-3000}}"
QUICK_MODE=false
ALL_MODE=false
while [[ $# -gt 0 ]]; do
case $1 in
--quick) QUICK_MODE=true; shift ;;
--all) ALL_MODE=true; shift ;;
-h|--help)
echo "Usage: $0 [--quick] [--all]"
echo " --quick Skip slow demos, just show what's available"
echo " --all Run all demos including voice (requires audio files)"
exit 0
;;
*) shift ;;
esac
done
#=============================================================================
# Helpers
#=============================================================================
header() {
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BOLD}${CYAN} $1${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
demo() {
echo -e "\n${MAGENTA}${NC} ${BOLD}$1${NC}"
}
success() {
echo -e "${GREEN}${NC} $1"
}
fail() {
echo -e "${RED}${NC} $1"
}
info() {
echo -e "${CYAN}${NC} $1"
}
wait_key() {
if [[ "$QUICK_MODE" != "true" ]]; then
echo -e "\n${YELLOW}Press Enter to continue...${NC}"
read -r
fi
}
check_service() {
local name=$1
local url=$2
local endpoint=${3:-/health}
if curl -sf "${url}${endpoint}" > /dev/null 2>&1; then
success "$name is running at $url"
return 0
else
fail "$name not responding at $url"
return 1
fi
}
#=============================================================================
# Welcome
#=============================================================================
clear
echo ""
echo -e "${BOLD}${CYAN}"
cat << 'EOF'
OOOOO DDDD SSSSS
OO OO DD DD SS
OO OO DD DD SSS
OO OO DD DD SS
OOOOO DDDD SSSS
EOF
echo -e "${NC}"
echo -e "${BOLD}ODS - First Boot Demo${NC}"
echo -e "Everything runs on YOUR hardware. No cloud. No API costs. Full privacy.\n"
#=============================================================================
# Health Check
#=============================================================================
header "🔍 Checking Services"
SERVICES_OK=0
SERVICES_TOTAL=0
# Core services
((SERVICES_TOTAL++)) || true
if check_service "LLM (llama-server)" "$LLM_URL" "/health"; then
((SERVICES_OK++)) || true
LLM_AVAILABLE=true
else
LLM_AVAILABLE=false
fi
((SERVICES_TOTAL++)) || true
if check_service "Open WebUI" "$WEBUI_URL" "/"; then
((SERVICES_OK++)) || true
fi
# Optional services
if curl -sf "${WHISPER_URL}/health" > /dev/null 2>&1; then
success "Whisper STT is running (voice input enabled)"
WHISPER_AVAILABLE=true
((SERVICES_OK++)) || true
((SERVICES_TOTAL++)) || true
else
info "Whisper STT not running (voice input disabled)"
WHISPER_AVAILABLE=false
fi
if curl -sf "${PIPER_URL}" > /dev/null 2>&1; then
success "OpenTTS TTS is running (voice output enabled)"
PIPER_AVAILABLE=true
((SERVICES_OK++)) || true
((SERVICES_TOTAL++)) || true
else
info "OpenTTS TTS not running (voice output disabled)"
PIPER_AVAILABLE=false
fi
if curl -sf "${N8N_URL}/healthz" > /dev/null 2>&1; then
success "n8n Workflows is running (automation enabled)"
N8N_AVAILABLE=true
((SERVICES_OK++)) || true
((SERVICES_TOTAL++)) || true
else
info "n8n not running (automation disabled)"
N8N_AVAILABLE=false
fi
echo ""
echo -e "${BOLD}Services: ${SERVICES_OK}/${SERVICES_TOTAL} running${NC}"
if [[ "$LLM_AVAILABLE" != "true" ]]; then
echo -e "\n${RED}LLM (llama-server) is required for demos. Is it still loading?${NC}"
echo "Check status: docker compose logs -f llama-server"
exit 1
fi
wait_key
#=============================================================================
# Demo 1: Chat Completion
#=============================================================================
header "💬 Demo 1: Local Chat Completion"
demo "Asking your local AI a question..."
RESPONSE=$(curl -sf "${LLM_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-32B-Instruct-AWQ",
"messages": [{"role": "user", "content": "In one sentence, what makes local AI special?"}],
"max_tokens": 100,
"temperature": 0.7
}' 2>/dev/null | jq -r '.choices[0].message.content' 2>/dev/null || echo "")
if [[ -n "$RESPONSE" && "$RESPONSE" != "null" ]]; then
echo ""
echo -e "${GREEN}Response:${NC}"
echo -e " ${RESPONSE}"
echo ""
success "Local LLM responded! No API calls, no cloud, just your GPU."
else
fail "No response from LLM"
fi
wait_key
#=============================================================================
# Demo 2: Code Assistance
#=============================================================================
header "🧑‍💻 Demo 2: Code Assistance"
demo "Asking for help with a Python function..."
CODE_RESPONSE=$(curl -sf "${LLM_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-32B-Instruct-AWQ",
"messages": [{"role": "user", "content": "Write a Python one-liner to reverse a string. Just the code, no explanation."}],
"max_tokens": 50,
"temperature": 0.3
}' 2>/dev/null | jq -r '.choices[0].message.content' 2>/dev/null || echo "")
if [[ -n "$CODE_RESPONSE" && "$CODE_RESPONSE" != "null" ]]; then
echo ""
echo -e "${GREEN}Generated code:${NC}"
echo -e " ${CODE_RESPONSE}"
echo ""
success "Code assistant works! Great for development."
else
fail "No response from code assistant"
fi
wait_key
#=============================================================================
# Demo 3: Streaming
#=============================================================================
header "📡 Demo 3: Streaming Response"
demo "Watching tokens stream in real-time..."
echo ""
# Simple streaming demo - just show it works
curl -sN "${LLM_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-32B-Instruct-AWQ",
"messages": [{"role": "user", "content": "Count from 1 to 5, one number per line."}],
"max_tokens": 50,
"temperature": 0,
"stream": true
}' 2>/dev/null | while read -r line; do
if [[ "$line" == data:* ]]; then
content=$(echo "${line#data: }" | jq -r '.choices[0].delta.content // empty' 2>/dev/null)
if [[ -n "$content" ]]; then
printf "%s" "$content"
fi
fi
done
echo ""
echo ""
success "Streaming works! Great for real-time UIs."
wait_key
#=============================================================================
# Summary
#=============================================================================
header "🎉 Demo Complete!"
echo ""
echo -e "${BOLD}What you just saw:${NC}"
echo " ✓ Local LLM responding to prompts"
echo " ✓ Code assistance capabilities"
echo " ✓ Real-time streaming"
echo ""
echo -e "${BOLD}What's available:${NC}"
echo " • Open WebUI: ${WEBUI_URL}"
[[ "$N8N_AVAILABLE" == "true" ]] && echo " • n8n Workflows: ${N8N_URL}"
[[ "$WHISPER_AVAILABLE" == "true" ]] && echo " • Whisper STT: ${WHISPER_URL}"
[[ "$PIPER_AVAILABLE" == "true" ]] && echo " • OpenTTS TTS: ${PIPER_URL}"
echo ""
echo -e "${BOLD}Next steps:${NC}"
echo " 1. Open ${WEBUI_URL} and start chatting"
echo " 2. Import workflows from ./workflows/ into n8n"
echo " 3. Try the voice demo: ./scripts/voice-demo.sh"
echo " 4. OpenClaw agent: http://localhost:7860"
echo ""
echo -e "${CYAN}Everything runs locally. Your data stays private. Enjoy! 🚀${NC}"
echo ""