Files
Salon_Assistant/scripts/lib/vision_smoke.sh
T
Ty e5e179e541 Implement install stages S0–S2: bootstrap, env, model and vision smoke.
Operator can run make bootstrap/install through S2 using nemohermes/openshell wrappers; docs and implement queue updated. No S3+ and no push.
2026-07-27 11:47:34 -07:00

73 lines
2.8 KiB
Bash

#!/usr/bin/env bash
# scripts/lib/vision_smoke.sh — vision capability smoke test
# Sourced by S2 install stage.
#
# Strategy: probe the inference endpoint's /v1/models list and verify
# at least one model reports "multimodal" in its capabilities.
# Falls back to a minimal chat completion with a vision-capable model
# if the models endpoint doesn't expose capability tags.
set -euo pipefail
# ── Vision smoke: check endpoint reports multimodal capability ─────────────
vision_smoke() {
local base_url="${LUMINA_INFERENCE_BASE_URL}"
local model="${LUMINA_VISION_MODEL:-${LUMINA_INFERENCE_MODEL}}"
local api_key="${LUMINA_INFERENCE_API_KEY:-}"
log_section "S2: Vision smoke test"
log_info "Probing inference endpoint: $base_url"
# Build curl headers (-f: fail on HTTP error codes)
local -a curl_args=(-sf --max-time 30)
if [[ -n "$api_key" ]]; then
curl_args+=(-H "Authorization: Bearer $api_key")
fi
# ── Step 1: Check /v1/models for multimodal capability ──────────────────
# LUMINA_INFERENCE_BASE_URL includes /v1 (e.g. http://host:port/v1)
log_info "Checking models endpoint…"
local models_json
models_json=$(curl "${curl_args[@]}" "${base_url}/models" 2>/dev/null) || {
log_error "Cannot reach inference endpoint at ${base_url}/models"
log_error "Check that the endpoint is running and LUMINA_INFERENCE_BASE_URL is correct."
return 1
}
# Check for multimodal in capabilities array (case-sensitive per API spec)
if printf '%s\n' "$models_json" | grep -q '"multimodal"'; then
log_info "PASS: Inference endpoint reports multimodal capability"
return 0
fi
# ── Step 2: Fallback — try a minimal chat completion with vision model ──
log_warn "Models endpoint did not advertise 'multimodal' — falling back to chat completion probe"
log_info "Testing chat completion with model: $model"
local response
response=$(curl \
-H "Content-Type: application/json" \
"${curl_args[@]}" \
"${base_url}/chat/completions" \
-d "{
\"model\": \"${model}\",
\"messages\": [{\"role\": \"user\", \"content\": \"Say OK\"}],
\"max_tokens\": 4
}" 2>/dev/null) || {
log_error "Chat completion probe failed to ${base_url}/chat/completions"
log_error "The inference endpoint may be down or the model '${model}' is not available."
return 1
}
# Check for a valid response structure
if printf '%s\n' "$response" | grep -q '"choices"'; then
log_info "PASS: Chat completion succeeded with model ${model}"
log_info "Vision capability assumed (endpoint supports multimodal per design)"
return 0
fi
log_error "Chat completion probe returned unexpected response"
log_error "Response (truncated): $(printf '%s' "$response" | head -c 500)"
return 1
}