Go daemon (cmd/llama-sidecar): per-agent llama-server process pool with LRU eviction, OpenAI-compatible proxy, flag validation (Unsloth port), deterministic hash-keyed sidecar reuse. Windows service support via schtasks/NSSM with DETACHED_PROCESS, stdout pipe drain, and request-ctx decoupled child lifetime. Bug fixes (3b.1–3b5): -c flag drop from StripShadowingFlags, UTF-8 BOM in JSON config, -fa → --flash-attn on default, child process exit after one request (stdin devnull, stdout pipe, CREATE_NO_WINDOW → DETACHED, context.Background for child lifetime, background reaper goroutine). bench/: MTP on/off throughput sweep across 8 GGUFs via SSH+schtasks automation to sam-desktop. Per-GGUF production flags from llama-swap config with --ctx-size 32768 override. eval/: accuracy benchmarks (MMLU 100q, GSM8K 50q, HumanEval 164) + A/B model comparison (14 agent-typed prompts × 8 models). All scripts resumable at individual question level. 94 Go tests, race detector clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
package pool
|
|
|
|
import (
|
|
"math/rand"
|
|
"testing"
|
|
)
|
|
|
|
func TestHash_OrderIndependence(t *testing.T) {
|
|
flags1 := []string{"--a", "1", "--b", "2", "--c", "3"}
|
|
h1 := Hash("foo", flags1)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
shuffled := make([]string, len(flags1))
|
|
copy(shuffled, flags1)
|
|
// Shuffle pairs (each pair is 2 tokens)
|
|
pairs := make([][2]string, 0)
|
|
for j := 0; j < len(shuffled); j += 2 {
|
|
pairs = append(pairs, [2]string{shuffled[j], shuffled[j+1]})
|
|
}
|
|
rand.Shuffle(len(pairs), func(a, b int) { pairs[a], pairs[b] = pairs[b], pairs[a] })
|
|
var flat []string
|
|
for _, p := range pairs {
|
|
flat = append(flat, p[0], p[1])
|
|
}
|
|
h := Hash("foo", flat)
|
|
if h != h1 {
|
|
t.Errorf("iteration %d: hash %s != %s for order %v", i, h, h1, flat)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHash_SeparatorCollision(t *testing.T) {
|
|
h1 := Hash("foo", []string{"--a\x1eb", "1"})
|
|
h2 := Hash("foo", []string{"--ab", "1"})
|
|
if h1 == h2 {
|
|
t.Error("separator collision: hashes should differ")
|
|
}
|
|
}
|
|
|
|
func TestHash_Length(t *testing.T) {
|
|
h := Hash("model", []string{"--top-k", "20"})
|
|
if len(h) != 16 {
|
|
t.Errorf("expected 16 hex chars, got %d: %s", len(h), h)
|
|
}
|
|
}
|
|
|
|
func TestHash_DifferentModels(t *testing.T) {
|
|
h1 := Hash("model-a", []string{"--top-k", "20"})
|
|
h2 := Hash("model-b", []string{"--top-k", "20"})
|
|
if h1 == h2 {
|
|
t.Error("different models should produce different hashes")
|
|
}
|
|
}
|