Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion internal/inference/llama.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,17 @@ func findLlamaBinary() string {
}
}

// Prefer a llama-server installed next to csghub-lite. Background services
// often receive a smaller or differently ordered PATH than the interactive
// shell that ran the installer; searching PATH first can therefore select a
// stale system-wide llama-server instead of the matching co-located release.
exePath, _ := os.Executable()
if sibling := llamaBinarySiblingPath(exePath, runtime.GOOS); sibling != "" {
if _, err := os.Stat(sibling); err == nil {
return sibling
}
}

// Search common names in PATH
names := []string{"llama-server", "llama.cpp-server", "llamacpp-server"}
for _, name := range names {
Expand All @@ -120,7 +131,6 @@ func findLlamaBinary() string {
}
// Check common install locations
home, _ := os.UserHomeDir()
exePath, _ := os.Executable()
for _, loc := range llamaBinaryCandidatePaths(home, exePath, runtime.GOOS) {
if _, err := os.Stat(loc); err == nil {
return loc
Expand All @@ -129,6 +139,17 @@ func findLlamaBinary() string {
return ""
}

func llamaBinarySiblingPath(exePath, goos string) string {
if strings.TrimSpace(exePath) == "" {
return ""
}
name := "llama-server"
if goos == "windows" {
name += ".exe"
}
return filepath.Join(filepath.Dir(exePath), name)
}

func llamaBinaryCandidatePaths(home, exePath, goos string) []string {
name := "llama-server"
if goos == "windows" {
Expand Down
14 changes: 14 additions & 0 deletions internal/inference/llama_binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import (
"testing"
)

func TestLlamaBinarySiblingPath(t *testing.T) {
wantName := "llama-server"
if runtime.GOOS == "windows" {
wantName += ".exe"
}
want := filepath.Join("opt", "csghub-lite", wantName)
if got := llamaBinarySiblingPath(filepath.Join("opt", "csghub-lite", "csghub-lite"), runtime.GOOS); got != want {
t.Fatalf("llamaBinarySiblingPath() = %q, want %q", got, want)
}
if got := llamaBinarySiblingPath("", runtime.GOOS); got != "" {
t.Fatalf("llamaBinarySiblingPath(empty) = %q, want empty", got)
}
}

func TestLlamaBinaryCandidatePathsIncludesInstallerLocations(t *testing.T) {
home := filepath.Join("Users", "james")
exePath := filepath.Join(home, ".local", "bin", "csghub-lite")
Expand Down
5 changes: 5 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -799,12 +799,17 @@ install_llama_server() {
# @rpath against those compatibility names, not just the versioned payload files.
if [ -w "$_llama_dir" ]; then
find "$_tmpdir" \( -type f -o -type l \) \( -name "*.dylib" -o -name "*.so" -o -name "*.so.*" \) | while read -r _lib; do
# mv may follow an existing destination symlink instead of replacing
# it, leaving compatibility links pinned to the previous release.
# Remove only the exact incoming basename before installing it.
rm -f "${_llama_dir}/$(basename "$_lib")"
mv "$_lib" "$_llama_dir/"
done
mv "$_llama_bin" "$_llama_dir/"
else
info "Requires root privileges to install llama-server."
find "$_tmpdir" \( -type f -o -type l \) \( -name "*.dylib" -o -name "*.so" -o -name "*.so.*" \) | while read -r _lib; do
run_privileged rm -f "${_llama_dir}/$(basename "$_lib")"
run_privileged mv "$_lib" "$_llama_dir/"
done
run_privileged mv "$_llama_bin" "$_llama_dir/"
Expand Down