#!/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 }