A local-first, collaborative AI assistant that works for you. Built with open models and decentralized protocols. www.tiles.run
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151#!/usr/bin/env bash# Provision the llama-server binary that powers Tiles inference.# - Linux: download a prebuilt CUDA or Vulkan binary.# CUDA defaults to the latest ai-dock release; Vulkan defaults to b9867.# - macOS: download the official prebuilt Metal release from llama.cpp.## Linux (CUDA): the downloaded binary links against CUDA 12.8 runtime# libraries, which must be present on the host for llama-server to start.## Environment variables:# TILES_LLAMA_BACKEND Linux backend: cuda (default) or vulkan.# LLAMA_CPP_TAG Pin a specific release tag (e.g. b10276).# TILES_CUDA_VERSION CUDA version suffix for the asset (default: 12.8).# Only used when LLAMA_CPP_TAG is pinned; the auto-# latest path reads the version from the asset name.# FORCE_LLAMA_FETCH Set to 1 to re-download even if a binary is present.set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"OUT_DIR="${ROOT}/server/bin"OS="$(uname -s)"
if [[ "${OS}" == "Darwin" ]]; then BACKEND="${TILES_LLAMA_BACKEND:-metal}" [[ "${BACKEND}" == "metal" ]] || { echo "Unsupported macOS llama backend: ${BACKEND}" >&2; exit 1; }elif [[ "${OS}" == "Linux" ]]; then BACKEND="${TILES_LLAMA_BACKEND:-cuda}" [[ "${BACKEND}" == "cuda" || "${BACKEND}" == "vulkan" ]] || { echo "Unsupported Linux llama backend: ${BACKEND}" >&2; exit 1; }else echo "Unsupported OS: ${OS}" >&2 exit 1fi
mkdir -p "${OUT_DIR}"
# Reuse an already-provisioned binary. Set FORCE_LLAMA_FETCH=1 to re-download.if [[ -x "${OUT_DIR}/llama-server" && -f "${OUT_DIR}/.llama-backend" \ && "$(<"${OUT_DIR}/.llama-backend")" == "${BACKEND}" \ && "${FORCE_LLAMA_FETCH:-}" != "1" ]]; then echo "llama-server already present at ${OUT_DIR}/llama-server; skipping fetch (set FORCE_LLAMA_FETCH=1 to force)." exit 0fi
# ---------------------------------------------------------------------------# macOS: official prebuilt Metal release from ggml-org/llama.cpp.# --------------------------------------------------------------------------if [[ "${OS}" == "Darwin" ]]; then LLAMA_CPP_TAG="${LLAMA_CPP_TAG:-b9867}" ARCH="$(uname -m)" case "${ARCH}" in arm64) ASSET="llama-${LLAMA_CPP_TAG}-bin-macos-arm64.tar.gz" ;; x86_64) ASSET="llama-${LLAMA_CPP_TAG}-bin-macos-x64.tar.gz" ;; *) echo "Unsupported macOS architecture: ${ARCH}" >&2; exit 1 ;; esac
URL="https://github.com/ggml-org/llama.cpp/releases/download/${LLAMA_CPP_TAG}/${ASSET}" TMP="$(mktemp -d)" echo "Downloading ${ASSET} (Metal prebuilt)" curl -fL -o "${TMP}/${ASSET}" "${URL}" tar -xzf "${TMP}/${ASSET}" -C "${TMP}"
SERVER_BIN="$(find "${TMP}" -type f -name llama-server | head -1)" if [[ -z "${SERVER_BIN}" ]]; then echo "llama-server not found inside ${ASSET}" >&2 exit 1 fi BIN_DIR="$(dirname "${SERVER_BIN}")" cp "${SERVER_BIN}" "${OUT_DIR}/llama-server" # cp -a preserves the .dylib -> .dylib.N -> .dylib.N.M.K symlink chain; # a plain cp dereferences it into 3 real copies of every library. cp -a "${BIN_DIR}/"*.dylib "${OUT_DIR}/" 2>/dev/null || true cp -a "${BIN_DIR}/"*.metal* "${OUT_DIR}/" 2>/dev/null || true chmod +x "${OUT_DIR}/llama-server" printf '%s\n' "${BACKEND}" > "${OUT_DIR}/.llama-backend" rm -rf "${TMP}" echo "Installed ${OUT_DIR}/llama-server (macOS Metal, ${LLAMA_CPP_TAG})" exit 0fi
# ---------------------------------------------------------------------------# Linux: prebuilt CUDA or Vulkan binary.# --------------------------------------------------------------------------ARCH="$(uname -m)"case "${ARCH}" in x86_64) ASSET_ARCH="amd64"; OFFICIAL_ARCH="x64" ;; aarch64|arm64) ASSET_ARCH="arm64"; OFFICIAL_ARCH="arm64" ;; *) echo "Unsupported Linux architecture: ${ARCH}" >&2; exit 1 ;;esac
API_URL="https://api.github.com/repos/ai-dock/llama.cpp-cuda/releases/latest"
if [[ "${BACKEND}" == "vulkan" ]]; then TAG="${LLAMA_CPP_TAG:-b9867}" ASSET="llama-${TAG}-bin-ubuntu-vulkan-${OFFICIAL_ARCH}.tar.gz" URL="https://github.com/ggml-org/llama.cpp/releases/download/${TAG}/${ASSET}"elif [[ -n "${LLAMA_CPP_TAG:-}" ]]; then # Pinned tag: construct the URL directly. CUDA version comes from the # override (default 12.8), since the API isn't queried. CUDA_VERSION="${TILES_CUDA_VERSION:-12.8}" TAG="${LLAMA_CPP_TAG}" ASSET="llama.cpp-${TAG}-cuda-${CUDA_VERSION}-${ASSET_ARCH}.tar.gz" URL="https://github.com/ai-dock/llama.cpp-cuda/releases/download/${TAG}/${ASSET}"else # Auto-latest: query the GitHub API. jq picks the asset matching our arch. echo "Querying ai-dock/llama.cpp-cuda latest release..." API_JSON="$(curl -fsSL "${API_URL}")" TAG="$(printf '%s' "${API_JSON}" | jq -r '.tag_name')" if [[ -z "${TAG}" || "${TAG}" == "null" ]]; then echo "Failed to determine latest ai-dock release tag" >&2 exit 1 fi URL="$(printf '%s' "${API_JSON}" | jq -r --arg arch "${ASSET_ARCH}" \ '.assets[] | select(.name | endswith("-" + $arch + ".tar.gz")) | .browser_download_url')" if [[ -z "${URL}" || "${URL}" == "null" ]]; then echo "No asset matching arch ${ASSET_ARCH} in ai-dock release ${TAG}" >&2 exit 1 fi ASSET="$(basename "${URL}")" # Asset name is llama.cpp-<tag>-cuda-<version>-<arch>.tar.gz; extract the # CUDA version so the runtime note below reports the actual selected value. if [[ "${ASSET}" =~ -cuda-([0-9.]+)- ]]; then CUDA_VERSION="${BASH_REMATCH[1]}" else CUDA_VERSION="unknown" fifi
TMP="$(mktemp -d)"trap 'rm -rf "${TMP}"' EXITecho "Downloading ${ASSET} (prebuilt ${BACKEND}, ${TAG})"curl -fL -o "${TMP}/${ASSET}" "${URL}"tar -xzf "${TMP}/${ASSET}" -C "${TMP}"
SERVER_BIN="$(find "${TMP}" -type f -name llama-server | head -1)"if [[ -z "${SERVER_BIN}" ]]; then echo "llama-server not found inside ${ASSET}" >&2 exit 1fiBIN_DIR="$(dirname "${SERVER_BIN}")"rm -f "${OUT_DIR}/llama-server" "${OUT_DIR}/"*.so* "${OUT_DIR}/.llama-backend"cp "${SERVER_BIN}" "${OUT_DIR}/llama-server"# Bring along bundled shared libs (libggml*.so etc.) if shipped next to it.# cp -a preserves the shared-library symlink chain.cp -a "${BIN_DIR}/"*.so* "${OUT_DIR}/" 2>/dev/null || truechmod +x "${OUT_DIR}/llama-server"printf '%s\n' "${BACKEND}" > "${OUT_DIR}/.llama-backend"echo "Installed ${OUT_DIR}/llama-server (Linux ${BACKEND} prebuilt, ${TAG})"if [[ "${BACKEND}" == "cuda" ]]; then echo "Note: requires CUDA ${CUDA_VERSION} runtime libraries on the host to run."fi