sci-misc/strata - 0.2.8 (pf4public)

Search

Install

Install this version:

emerge -a =sci-misc/strata-0.2.8

Package Information

Description:
Local LLM inference engine with an OpenAI/Anthropic-compatible API
Homepage:
https://github.com/Niko1221/Strata
License:
MIT

Ebuild Details

Version EAPI Keywords Slot
0.2.8 8 amd64 0
View Raw Ebuild
# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

REPO="https://github.com/Niko1221/Strata"
# the llama.cpp pin third_party/ggml/VERSION.txt points at: its ggml is built
# statically into the engine, and CMake would FetchContent the same commit
# from the network at configure time, so the ebuild pins it as a distfile
LLAMA_REPO="https://github.com/ggml-org/llama.cpp"
LLAMA_COMMIT="3cf03257f219afbe7334045ff7c6a06ac68c627d"
# system-ggml: the sci-ml/ggml package to link (bump with its bumps)
GGML_PV="0.28.0"
# the commit the v${PV} tag points at; the desktop control staging needs it
# (the tarball has no .git, so STRATA_COMMIT supplies it)
STRATA_TAG_COMMIT="878ef09cc9092a41a37dac32fd6fe461e47fa326"

ROCM_VERSION="7.2"

# the desktop (apps/desktop) tauri shell, from apps/desktop/src-tauri/
# Cargo.lock; the crates are not listed as distfiles but packed into the
# single files/strata-desktop-${PV}-crates.tar.xz (expanded in src_unpack)
CRATES="
"

RUST_MIN_VER="1.77"

inherit cargo cmake cuda linux-info rocm

DESCRIPTION="Local LLM inference engine with an OpenAI/Anthropic-compatible API"
HOMEPAGE="https://github.com/Niko1221/Strata"

SRC_URI="
	${CARGO_CRATE_URIS}
	${REPO}/archive/refs/tags/v${PV}.tar.gz -> ${P}.tar.gz
	!system-ggml? (
		${LLAMA_REPO}/archive/${LLAMA_COMMIT}.tar.gz -> ${P}-ggml-${LLAMA_COMMIT}.tar.gz
	)
	desktop? (
		https://nodejs.org/dist/v24.12.0/node-v24.12.0-linux-x64.tar.gz
		https://github.com/astral-sh/python-build-standalone/releases/download/20261009/cpython-3.12.15%2B20261009-x86_64-unknown-linux-gnu-install_only.tar.gz -> cpython-3.12.15_20261009-x86_64-unknown-linux-gnu-install_only.tar.gz
	)
"

S="${WORKDIR}/Strata-${PV}"

LICENSE="MIT"
SLOT="0"
KEYWORDS="amd64"

# the engine is built for one GPU backend; the terminal (the strata command,
# the monitor and the API server) installs in every case. system-ggml links
# the installed sci-ml/ggml instead of building the pinned commit's ggml
# (files/strata-system-ggml.patch adds the STRATA_SYSTEM_GGML option).
# desktop is the tauri app (apps/desktop): the Rust shell plus the host web
# shell, the pinned node runtime, the pinned CPython control component and
# (with cuda/hip) the engine bundle; the tauri shell locates the resources
# in <bindir>/../lib/strata-desktop, so the layout below is fixed
IUSE="cuda desktop hip system-ggml tui"
REQUIRED_USE="!cuda? ( !hip )"

# the terminal runs on the system python3 (the bin/strata launcher); these
# are the packages its requirements.txt pins; with system-ggml the engine
# links sci-ml/ggml, whose install also carries the source tree (src/ +
# include/) with the internal headers and the ggml-cuda MMQ sources strata
# compiles itself. The desktop's gui stack is the set the tauri shell links
# (best effort: the tauri build is not testable in CI)
COMMON_DEPEND="
	dev-python/jinja2
	dev-python/numpy
	dev-python/pillow
	dev-python/psutil
	dev-python/pyyaml
	dev-python/regex
	dev-python/requests
	dev-python/tqdm
	tui? ( dev-python/textual )
	cuda? ( dev-util/nvidia-cuda-toolkit:= )
	desktop? (
		dev-libs/glib
		net-libs/webkit-gtk:4.1
		x11-libs/gtk+:3
	)
	hip? (
		>=dev-util/hip-${ROCM_VERSION}:=
		>=sci-libs/hipBLAS-${ROCM_VERSION}:=
		>=sci-libs/rocBLAS-${ROCM_VERSION}:=
	)
	system-ggml? ( sci-ml/ggml:0/${GGML_PV}[src] )
"
RDEPEND="${COMMON_DEPEND}"
DEPEND="${COMMON_DEPEND}"
BDEPEND="
	desktop? (
		>=net-libs/nodejs-24.12[npm]
	)
"

PATCHES=( "${FILESDIR}/strata-9999-system-ggml.patch" )

pkg_pretend() {
	if use cuda && [[ -z ${CUDA_ARCHITECTURES} ]]; then
		einfo "CUDA_ARCHITECTURES is unset, so strata builds its default set of"
		einfo "CUDA compute capabilities (75/86/89/120 SASS, 120 PTX), which is slow."
		einfo "Set it to your GPU's compute capability to skip unused targets, e.g."
		einfo 'CUDA_ARCHITECTURES="75-real" (several are ; separated: "75-real;80-real").'
		einfo "  find: nvidia-smi --query-gpu=compute_cap --format=csv,noheader"
		einfo "  suffixes: 75 (PTX+SASS), 75-real (SASS only), 75-virtual (PTX only)"
	fi
}

pkg_setup() {
	if use desktop; then
		rust_pkg_setup
	fi
	if use hip; then
		linux-info_pkg_setup
		if linux-info_get_any_version && linux_config_exists; then
			if ! linux_chkconfig_present HSA_AMD_SVM; then
				ewarn "To use ROCm/HIP, you need to have HSA_AMD_SVM option enabled in your kernel."
			fi
		fi
	fi
}

src_unpack() {
	cargo_src_unpack

	# the llama.cpp pin for the built-in ggml (not a distfile with
	# system-ggml; CMake would fetch the commit from the network)
	if ! use system-ggml; then
		mkdir -p "${WORKDIR}/llama.cpp-${LLAMA_COMMIT}" || die
		tar xzf "${DISTDIR}/${P}-ggml-${LLAMA_COMMIT}.tar.gz" \
			-C "${WORKDIR}/llama.cpp-${LLAMA_COMMIT}" --strip-components=1 || die
	fi

	# the locked runtime wheels for the desktop control component
	# (self-generated; not on a mirror, so it is kept in files/ and expanded
	# here)
	if use desktop; then
		mkdir -p "${WORKDIR}/wheels" || die
		tar xzf "${FILESDIR}/strata-runtime-wheels-linux-x86_64.tar.gz" \
			-C "${WORKDIR}/wheels" || die
	fi

	# the desktop crates (self-generated, kept in files/ like the wheelhouse);
	# expanded onto ${WORKDIR} without stripping so the cargo_home/gentoo
	# prefix lands on the cargo eclass' vendor dir
	if use desktop; then
		tar xJf "${FILESDIR}/strata-desktop-${PV}-crates.tar.xz" -C "${WORKDIR}" || die
	fi
}

src_prepare() {
	use cuda && cuda_src_prepare
	cmake_src_prepare

	# the engine version for the component folder name and the manifest
	ENGINE_PV=$(sed -n 's/^[[:space:]]*project([^)]*VERSION[[:space:]]*\([0-9][0-9.]*\).*/\1/p' \
		"${S}/CMakeLists.txt" | head -n 1)
	if use cuda || use hip; then
		[[ -n ${ENGINE_PV} ]] || die "cannot find the engine version in CMakeLists.txt"
	fi
}

src_configure() {
	if use desktop; then
		cargo_src_configure --manifest-path "${S}/apps/desktop/src-tauri/Cargo.toml"
	fi

	local ggml_dir
	if use system-ggml; then
		# the sci-ml/ggml install: the libraries to link + the source tree
		ggml_dir="/usr/$(get_libdir)/ggml-${GGML_PV}"
	else
		ggml_dir="${WORKDIR}/llama.cpp-${LLAMA_COMMIT}"
	fi

	local mycmakeargs=(
		# portable: the AVX2-baseline ggml-cpu instead of the build host's
		# -march=native; strata's own kernels are per-file and CPU-dispatched
		# at run time either way
		-DSTRATA_PORTABLE=ON
		-DSTRATA_NATIVE_EXPERTS=ON
		-DSTRATA_Q6K_EXPERTS=ON
		-DSTRATA_MMQ_KQUANTS=ON
		-DSTRATA_BUILD_TESTS=OFF
		# the ggml source (the pinned llama.cpp, or sci-ml/ggml's install);
		# without it CMake would fetch the pinned commit from the network
		-DSTRATA_GGML_DIR="${ggml_dir}"
		-DSTRATA_SYSTEM_GGML=$(usex system-ggml)
	)

	if use cuda; then
		mycmakeargs+=(
			-DSTRATA_ENABLE_CUDA=ON
			# CUDA_ARCHITECTURES (make.conf) restricts the compute capabilities,
			# see pkg_pretend; the default is the upstream recipe: RTX 20 / 30
			# / 40 / 50, the latest one with its PTX for forward compatibility
			-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHITECTURES:-75-real;86-real;89-real;120-real;120-virtual}"
		)
		local -x CUDAHOSTCXX="$(cuda_gccdir)"
		cuda_add_sandbox
		addpredict "/dev/char/"
	fi

	if use hip; then
		rocm_use_clang
		mycmakeargs+=(
			-DSTRATA_ENABLE_HIP=ON
			-DSTRATA_PREFILL_MMQ=ON
			# the validated wave32 targets; RDNA2 (gfx103x) is upstream-
			# experimental and left out
			-DCMAKE_HIP_ARCHITECTURES="gfx1100;gfx1201"
			-DCMAKE_HIP_FLAGS="${CXXFLAGS}"
			# cmake.eclass clears per-build-type flags for C/CXX only;
			# drop CMake's "-O2 -g -DNDEBUG" for HIP
			"-DCMAKE_HIP_FLAGS_${CMAKE_BUILD_TYPE^^}="
		)
	fi

	cmake_src_configure
}

src_compile() {
	if use desktop; then
		# the host web shell (vite); the tauri shell embeds apps/host/dist at
		# compile time, so this runs before cargo
		einfo "building the host UI"
		local -x NPM_CONFIG_CACHE="${WORKDIR}/.npm"
		(
			cd "${S}/apps/host" || die
			npm install --no-audit --no-fund || die
			npm run build || die
		)

		# tauri embeds every bundle.resources path into the binary (the
		# embedded copy is unused on linux: at runtime the app reads
		# <bindir>/../lib/strata-desktop), so every listed folder must exist
		# at compile time; harness is never staged (the app runs without it)
		mkdir -p "${S}/apps/desktop/src-tauri/resources/harness" || die

		cargo_src_compile
	fi

	if use cuda; then
		# strata_kq: the K-quant MMQ library the engine dlopens for the
		# Unsloth UD-Q4/Q5/Q6_K_XL experts
		cmake_src_compile strata strata_kq
	elif use hip; then
		cmake_src_compile strata
	fi
}

src_install() {
	local libdir="usr/$(get_libdir)/strata"

	# ---- the terminal: the strata command, the API server, the model installer ----
	insinto "/${libdir}"
	doins strata.py setup.py chat.py highlight.py requirements.txt requirements-monitor.txt
	doins -r strata_cli strata_control serve
	doins -r data

	insinto "/${libdir}/bench"
	doins -r bench/prompts

	insinto "/${libdir}/bin"
	doins bin/strata

	insinto "/${libdir}/ref"
	doins ref/load.py

	insinto "/${libdir}/docs"
	doins docs/MANAGEMENT_PROTOCOL.md docs/TERMINAL_LAUNCH.md

	insinto "/${libdir}"

	# the tools modules the terminal paths import: the same closure
	# packaging/package_terminal.py stages into its archive (under tools/,
	# subdirectories included), computed from the sources
	local stage t
	stage="${T}/tools-stage"
	mkdir -p "${stage}"
	while IFS= read -r t; do
		cp --parents "tools/${t}.py" "${stage}/"
	done < <(
		python3 - "${S}" <<'EOF'
import importlib.util, sys
spec = importlib.util.spec_from_file_location("pt", sys.argv[1] + "/packaging/package_terminal.py")
pt = importlib.util.module_from_spec(spec)
spec.loader.exec_module(pt)
names = set(pt.INSTALLER_TOOLS) | set(pt.INSTALLER_SCRIPTS) | set(pt.setup_tool_imports(pt.ROOT))
tools = pt.local_imports(pt.ROOT, tuple(sorted(names)))
[print(name[:-3] if name.endswith(".py") else name) for name in sorted(set(tools) | set(pt.TOOLS_SUBSET))]
EOF
	)
	doins -r "${stage}/tools"

	# the tarball ships it 0775
	fperms 0755 "${libdir}/bin/strata"

	# the terminal's own version label
	echo "${PV}" > "${D}/${libdir}/VERSION"

	# the launcher finds the python3 (3.10+) on the PATH
	dosym "../$(get_libdir)/strata/bin/strata" /usr/bin/strata

	# ---- the engine: an engine component the terminal verifies before a start ----
	if use cuda || use hip; then
		local backend stage arch_args
		use cuda && backend=cuda || backend=hip

		stage="${T}/engine-stage"
		mkdir -p "${stage}"
		cp "${BUILD_DIR}/strata" "${stage}/"
		if use cuda; then
			cp "${BUILD_DIR}/libstrata_kq.so" "${stage}/"
			# the component's archs are what the build actually targeted
			# (CUDA_ARCHITECTURES, see pkg_pretend)
			local cuda_archs arch num tokens token
			local -A arch_seen
			cuda_archs="${CUDA_ARCHITECTURES:-75-real;86-real;89-real;120-real;120-virtual}"
			arch_args=()
			for arch in ${cuda_archs//;/ }; do
				num=${arch%%-*}
				if [[ ${arch} == *-virtual ]]; then
					tokens="compute_${num}"
				elif [[ ${arch} == *-* ]]; then
					tokens="sm_${num}"
				else
					tokens="sm_${num} compute_${num}"
				fi
				for token in ${tokens}; do
					if [[ -z ${arch_seen[${token}]+x} ]]; then
						arch_seen[${token}]=1
						arch_args+=( --arch "${token}" )
					fi
				done
			done
			local cuda_pv arch_nums
			cuda_pv=$(nvcc --version 2>/dev/null | sed -n 's/.*release \([0-9][0-9]*\.[0-9][0-9]*\).*/\1/p')
			arch_nums=$(for arch in ${cuda_archs//;/ }; do
				echo "${arch%%-*}"
			done | sort -nu | paste -sd ';' -)
			cat > "${stage}/BUILD.json" <<-EOF
			{
				"version": "${ENGINE_PV}",
				"source": "gentoo ebuild",
				"archs": "${arch_nums}",
				"cuda": "${cuda_pv}",
				"portable": true
			}
			EOF
		else
			# the hipBLASLt version and the matching tuning tables for the
			# package; the ROCm install's include tree is /usr
			python3 "${S}/packaging/stage_tuning.py" --stage "${stage}" \
				--archs "gfx1100 gfx1201" --rocm /usr || die
			arch_args=( --arch gfx1100 --arch gfx1201 )
		fi

		# the engine imports the CUDA toolkit's libraries (cublas, cublasLt,
		# cudart); the packager refuses a component whose imports are neither
		# bundled nor OS or driver libraries. The toolkit's are allowed:
		# RDEPEND (nvidia-cuda-toolkit) provides them and its lib dir is in
		# the ldconfig cache
		local allow_args=()
		use cuda && allow_args=( --allow-lib libcublas.so.13 --allow-lib libcublasLt.so.13
			--allow-lib libcudart.so.13 )

		# the manifest (engine-component.json): strata hashes and verifies the
		# whole component before a start. The picture reader is not shipped,
		# so the image input stays off (the engine reports it as missing)
		python3 "${S}/packaging/package_engine.py" \
			--src "${stage}" \
			--backend "${backend}" \
			--version "${ENGINE_PV}" \
			--platform linux-x86_64 \
			--out "${D}/${libdir}/components/engine" \
			"${arch_args[@]}" \
			"${allow_args[@]}" \
			--build-id "gentoo-${PV}" \
			--no-picture-reader || die

		# estrip (after src_install) would break the component's integrity:
		# engine-component.json records the binaries' hashes, so the engine
		# must survive the install unstripped
		dostrip -x "/${libdir}/components/engine"

		local envd="${T}/90strata"
		cat > "${envd}" <<-EOF
		STRATA_COMPONENTS_DIR="/usr/$(get_libdir)/strata/components"
		export STRATA_COMPONENTS_DIR
		EOF
		doenvd "${envd}"
	fi

	# ---- the desktop: the tauri shell + the resources it locates beside it ----
	if use desktop; then
		local desktopdir="usr/$(get_libdir)/strata-desktop"

		cp "${S}/apps/desktop/src-tauri/target/release/strata-desktop" "${T}/strata-desktop" || die
		insinto /usr/bin
		doins "${T}/strata-desktop"
		fperms 0755 /usr/bin/strata-desktop

		# the web shell + engine host: node starts host/server/index.mjs
		insinto "/${desktopdir}/host"
		doins -r "${S}/apps/host/dist" "${S}/apps/host/server"
		doins "${S}/apps/host/package.json"

		# the pinned node runtime (the single binary the host uses)
		insinto "/${desktopdir}/node"
		doins "${WORKDIR}/node-v24.12.0-linux-x64/bin/node"
		fperms 0755 "/${desktopdir}/node/node"

		# control: the pinned CPython + the locked wheels + the python parts
		# of strata, staged and self-verified by the upstream script. The
		# interpreter distfile is pre-placed in its cache, the wheels come
		# from files/, so this fetches nothing
		local -x STRATA_COMMIT="${STRATA_TAG_COMMIT}"
		local -x TMPDIR="${T}"
		mkdir -p "${T}/strata-packaging-cache" || die
		cp "${DISTDIR}/cpython-3.12.15_20261009-x86_64-unknown-linux-gnu-install_only.tar.gz" \
			"${T}/strata-packaging-cache/" || die
		python3 "${S}/apps/desktop/scripts/stage-control.py" \
			--out "${D}/${desktopdir}/control" \
			--wheelhouse "${WORKDIR}/wheels" || die

		# the pinned CPython is fragile: strip corrupts its dynamic section
		# (its .dynstr is not in a segment) and the interpreter stops running
		dostrip -x "/usr/$(get_libdir)/strata-desktop/control"

		# the engine bundle: the same component the terminal installs, so
		# the app ships with its engine
		if use cuda || use hip; then
			local comp
			mkdir -p "${D}/${desktopdir}/engine-bundle" || die
			for comp in "${D}/${libdir}/components/engine"/*; do
				[[ -e ${comp} ]] || continue
				cp -a "${comp}" "${D}/${desktopdir}/engine-bundle/" || die
			done
		fi
	fi

	dodoc README.md
}

pkg_postinst() {
	if ! use cuda && ! use hip; then
		ewarn "No engine was built (enable the cuda or hip USE flag for an"
		ewarn "NVIDIA / AMD GPU). The strata terminal is installed, but"
		ewarn "'strata launch' needs an engine: re-emerge sci-misc/strata with"
		ewarn "[cuda] or [hip] to build one."
	fi
}

USE Flags

Manage flags for this package: euse -i <flag> -p sci-misc/strata | euse -E <flag> -p sci-misc/strata | euse -D <flag> -p sci-misc/strata

Global/Standard Flags

hip
tui

Inherited Eclasses

Dependencies

DEPEND

	dev-python/jinja2
	dev-python/numpy
	dev-python/pillow
	dev-python/psutil
	dev-python/pyyaml
	dev-python/regex
	dev-python/requests
	dev-python/tqdm
	tui? ( dev-python/textual )
	cuda? ( dev-util/nvidia-cuda-toolkit:= )
	desktop? (
		dev-libs/glib
		net-libs/webkit-gtk:4.1
		x11-libs/gtk+:3
	)
	hip? (
		>=dev-util/hip-7.2:=
		>=sci-libs/hipBLAS-7.2:=
		>=sci-libs/rocBLAS-7.2:=
	)
	system-ggml? ( sci-ml/ggml:0/0.28.0[src] )

RDEPEND

	dev-python/jinja2
	dev-python/numpy
	dev-python/pillow
	dev-python/psutil
	dev-python/pyyaml
	dev-python/regex
	dev-python/requests
	dev-python/tqdm
	tui? ( dev-python/textual )
	cuda? ( dev-util/nvidia-cuda-toolkit:= )
	desktop? (
		dev-libs/glib
		net-libs/webkit-gtk:4.1
		x11-libs/gtk+:3
	)
	hip? (
		>=dev-util/hip-7.2:=
		>=sci-libs/hipBLAS-7.2:=
		>=sci-libs/rocBLAS-7.2:=
	)
	system-ggml? ( sci-ml/ggml:0/0.28.0[src] )

BDEPEND

	desktop? (
		>=net-libs/nodejs-24.12[npm]
	)

Manifest for 0.2.8

Type File Size Source URLs
DIST cpython-3.12.15_20261009-x86_64-unknown-linux-gnu-install_only.tar.gz 66913335 bytes https://github.com/astral-sh/python-build-standalone/releases/download/20261009/cpython-3.12.15%2B20261009-x86_64-unknown-linux-gnu-install_only.tar.gz
DIST node-v24.12.0-linux-x64.tar.gz 56331493 bytes https://nodejs.org/dist/v24.12.0/node-v24.12.0-linux-x64.tar.gz
DIST strata-0.2.8-ggml-3cf03257f219afbe7334045ff7c6a06ac68c627d.tar.gz 37513049 bytes https://github.com/ggml-org/llama.cpp/archive/3cf03257f219afbe7334045ff7c6a06ac68c627d.tar.gz
DIST strata-0.2.8.tar.gz 31429420 bytes https://github.com/Niko1221/Strata/archive/refs/tags/v0.2.8.tar.gz