CI / test (push) Successful in 9m15s
- Revoking a server's tools takes them from every level beneath too, and a level left naming no tool stays closed ([]) while any level above or beneath names tools: an organization's revoke left its teams the copies their first grants took, and going back to no list opened the level to what was above it. A closed level is shown on the page and in the console with an action to open it (store.OpenTools). A key's owner's list is among the levels above a key. - The flag check matches short flags as written again (-m, -hf, -mu were let through), takes a long flag's beginning for it only for the engines that parse with argparse (vLLM, SGLang, ComfyUI: --li is --listen), so llama.cpp's own --chat-template is not refused, and refuses llama.cpp's short spellings (-hfr, -hff, -mm, -jf, …). - A stored model with an adapter by Hugging Face id can be changed again: what it already had is not asked about anew. - The catalog reads a Hugging Face id as the agent does (engines.IsHubID). - The page's form cannot move llmgw:admin to another address. - server init skips the memory check only where the gateway already runs, not wherever a half-finished first run left server.yaml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.0 KiB
Go
59 lines
2.0 KiB
Go
package engines
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
)
|
|
|
|
func TestAModelDownloadedByTheEngineIsReadAsSafetensorsOnly(t *testing.T) {
|
|
for path, want := range map[string]bool{
|
|
"Qwen/Qwen2.5-7B-Instruct": true,
|
|
"/var/lib/llmgw/weights/abc/": false, "./local": false,
|
|
"http://m/q/v/": false, "q.gguf": false,
|
|
} {
|
|
got := slices.Contains(safetensorsOnly(Profile{ModelPath: path}), "safetensors")
|
|
if got != want {
|
|
t.Errorf("%q: safetensors only = %v, want %v", path, got, want)
|
|
}
|
|
}
|
|
if len(safetensorsOnly(Profile{ModelPath: "Qwen/Qwen2.5-7B-Instruct", AllowPickle: true})) != 0 {
|
|
t.Error("allow_pickle still forced safetensors")
|
|
}
|
|
}
|
|
|
|
func TestAForbiddenFlagIsKnownHoweverItIsSpelled(t *testing.T) {
|
|
for engine, args := range map[string][]string{
|
|
"vllm": {"--trust_remote_code"},
|
|
"sglang": {"--load-format", "pt"},
|
|
} {
|
|
if UnsafeArgs(engine, args) == nil {
|
|
t.Errorf("%s %v was let through", engine, args)
|
|
}
|
|
}
|
|
for _, a := range [][]string{{"--load_format", "pt"}, {"--trust-remote"}, {"--load-form=pt"}} {
|
|
if UnsafeArgs("vllm", a) == nil {
|
|
t.Errorf("vllm %v was let through", a)
|
|
}
|
|
}
|
|
// What is not one of them, nor the start of one, still passes.
|
|
for _, a := range [][]string{{"--max-model-len", "8192"}, {"--tokenizer-mode", "mistral"}, {"--gpu-memory-utilization=0.9"}} {
|
|
if err := UnsafeArgs("vllm", a); err != nil {
|
|
t.Errorf("vllm %v was refused: %v", a, err)
|
|
}
|
|
}
|
|
// Short flags are matched as written; llama.cpp takes no abbreviations,
|
|
// so its --chat-template is not taken for --chat-template-file.
|
|
for _, a := range [][]string{{"-m", "x"}, {"-hf", "o/r"}, {"-mu", "http://x"}} {
|
|
if UnsafeArgs("llamacpp", a) == nil {
|
|
t.Errorf("llamacpp %v was let through", a)
|
|
}
|
|
}
|
|
if err := UnsafeArgs("llamacpp", []string{"--chat-template", "chatml"}); err != nil {
|
|
t.Errorf("llama.cpp's own --chat-template was refused: %v", err)
|
|
}
|
|
// ComfyUI's argparse reads --li as --listen.
|
|
if UnsafeArgs("comfyui", []string{"--li", "0.0.0.0"}) == nil {
|
|
t.Error("comfyui --li was let through")
|
|
}
|
|
}
|