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
4 changes: 2 additions & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ builds:
# Commit is what identifies a dev build: they all share one moving
# release tag, so the version string can't tell two of them apart.
- -s -w
-X github.com/coder/vllm-helper/internal/cli.Version={{.Version}}
-X github.com/coder/vllm-helper/internal/cli.Commit={{.FullCommit}}
-X github.com/coder/llm-helper/internal/cli.Version={{.Version}}
-X github.com/coder/llm-helper/internal/cli.Commit={{.FullCommit}}
# The same binary under its old name. 'upgrade' in v0.5.0 and earlier
# unpacks the file called vllm-helper and nothing else, so dropping it would
# strand every existing install on the release it has.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ llm-helper is one Go binary that manages inference servers (vLLM, mlx-lm, llama.

## Repository layout

`internal/` holds the packages the binary builds from: `cli` for the commands, `control` for what the CLI and the web panel share, `web` for the panel, and the rest one package per feature. `catalogue/` holds the shipped data definitions (engines, recipes, hardware) with the Go that embeds them in `catalogue/catalogue.go`. `docs/` is the shipped documentation, and `tools/recipediff` is a separate module.
`internal/` holds the packages the binary builds from: `cli` for the commands, `control` for what the CLI and the web panel share, `web` for the panel, and the rest one package per feature. `catalogue/` holds the shipped data definitions (engines, recipes, hardware) with the Go that embeds them in `catalogue/catalogue.go`; each kind is read by the `internal/` package of the same name (`engine`, `recipe`, `hardware`), and `resolve` combines them with a model's card and config into launch settings. `docs/` is the shipped documentation, and `tools/recipediff` is a separate module.

## Essential commands

Expand Down
2 changes: 1 addition & 1 deletion catalogue/engines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Each file here is one inference server llm-helper can launch, named after the en

To add an engine, copy the closest file to `<id>.json` and change it.
No Go code is needed: shared code acts on the engine's `capabilities`, never on its name.
The file is checked when it loads, and the tests in `internal/provider` render every file here for every rank.
The file is checked when it loads, and the tests in `internal/engine` render every file here for every rank.

The fields are described in "Contributing an engine" in [docs/providers.md](../../docs/providers.md).
To try an engine without rebuilding, put its file in `~/.config/vllm-helper/engines.d/` instead.
2 changes: 1 addition & 1 deletion cmd/vllm-helper-docs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"syscall"
"time"

"github.com/coder/vllm-helper/internal/web"
"github.com/coder/llm-helper/internal/web"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion docs/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/docs"
"github.com/coder/llm-helper/docs"
)

// The manifest is the docs engine's contract with the panel: one entry per
Expand Down
2 changes: 1 addition & 1 deletion docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ A definition holds `schema_version` and the engine's fields, and says:
The definition is checked when it loads.
An unknown field, an unknown placeholder, a key that would land on the command line, or a container with no role that serves HTTP is refused with the reason.
A file whose name is not its id is refused too.
The tests in `internal/provider` render every shipped engine for every rank, so a new engine is covered once its file is in `catalogue/engines/`.
The tests in `internal/engine` render every shipped engine for every rank, so a new engine is covered once its file is in `catalogue/engines/`.

To try an engine without rebuilding, put its file under `~/.config/vllm-helper/engines.d/`, in the same shape and named the same way as a file in `catalogue/engines/`.
A local file can only add engines with new ids; it cannot change how a shipped engine is launched.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/coder/vllm-helper
module github.com/coder/llm-helper

go 1.26.5

Expand Down
4 changes: 2 additions & 2 deletions internal/cli/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"fmt"
"os"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/vllm"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/vllm"
)

// vllmCaps asks the configured vLLM what it supports, caching under the state
Expand Down
10 changes: 5 additions & 5 deletions internal/cli/clusterrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"strconv"
"strings"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/control"
"github.com/coder/vllm-helper/internal/profile"
"github.com/coder/vllm-helper/internal/recipe"
"github.com/coder/vllm-helper/internal/service"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/control"
"github.com/coder/llm-helper/internal/profile"
"github.com/coder/llm-helper/internal/recipe"
"github.com/coder/llm-helper/internal/service"
)

// clusterRunner drives a recipe that serves from containers on the nodes it
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/clusterrunner_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/internal/nodes"
"github.com/coder/llm-helper/internal/nodes"
)

// status reads this vocabulary, so a mistranslation here is what makes a
Expand Down
38 changes: 19 additions & 19 deletions internal/cli/detectcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (

"github.com/spf13/cobra"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/control"
"github.com/coder/vllm-helper/internal/detect"
"github.com/coder/vllm-helper/internal/hardware"
"github.com/coder/vllm-helper/internal/hf"
"github.com/coder/vllm-helper/internal/plugin"
"github.com/coder/vllm-helper/internal/profile"
"github.com/coder/vllm-helper/internal/provider"
"github.com/coder/vllm-helper/internal/recipe"
"github.com/coder/vllm-helper/internal/toolchain"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/control"
"github.com/coder/llm-helper/internal/detect"
"github.com/coder/llm-helper/internal/engine"
"github.com/coder/llm-helper/internal/hardware"
"github.com/coder/llm-helper/internal/hf"
"github.com/coder/llm-helper/internal/plugin"
"github.com/coder/llm-helper/internal/profile"
"github.com/coder/llm-helper/internal/recipe"
"github.com/coder/llm-helper/internal/toolchain"
)

// doctorReport is everything doctor learns, in one machine-readable shape.
Expand Down Expand Up @@ -139,14 +139,14 @@ func gatherDoctor() doctorReport {
HarmonyVocab: hasHarmonyVocab(cfg.Dirs.Data),
CoderConfigured: cfg.CoderConfigured(),
}
if prov, err := provider.Lookup(cfg.Provider()); err != nil {
if prov, err := engine.Lookup(cfg.Provider()); err != nil {
r.Config.Provider = cfg.Provider()
r.Config.ProviderError = err.Error()
} else {
r.Config.Provider = prov.Name()
if prov.Name() != provider.VLLM {
if prov.Name() != engine.VLLM {
r.Config.ProviderBin = cfg.Lookup(prov.BinKey(), "")
r.Config.ProviderBinOK = provider.Executable(r.Config.ProviderBin)
r.Config.ProviderBinOK = engine.Executable(r.Config.ProviderBin)
}
}
}
Expand Down Expand Up @@ -274,7 +274,7 @@ func hardwareWarnings(hw detect.Hardware) []string {
for _, err := range hardware.LocalErrors() {
w = append(w, "a local hardware definition was skipped: "+err.Error())
}
for _, err := range provider.LocalErrors() {
for _, err := range engine.LocalErrors() {
w = append(w, "a local engine definition was skipped: "+err.Error())
}
for _, err := range recipe.LocalErrors() {
Expand Down Expand Up @@ -387,7 +387,7 @@ func renderDoctor(r doctorReport, yes bool) {
if hw.GPUsHidden > 0 {
fmt.Printf(" %d more hidden from the server by CUDA_VISIBLE_DEVICES\n", hw.GPUsHidden)
}
newProfiles := provider.VLLM
newProfiles := engine.VLLM
if r.Config != nil {
newProfiles = r.Config.Provider
}
Expand Down Expand Up @@ -433,8 +433,8 @@ func renderDoctor(r doctorReport, yes bool) {
switch {
case c.ProviderError != "":
fmt.Printf(" provider: %s\n", c.ProviderError)
case c.Provider != provider.VLLM:
p, _ := provider.Lookup(c.Provider)
case c.Provider != engine.VLLM:
p, _ := engine.Lookup(c.Provider)
fmt.Printf(" provider: %s (new profiles)\n", c.Provider)
// "server", not "<provider> bin": the line above names the provider,
// and a longer name would push the value out of the column.
Expand All @@ -451,7 +451,7 @@ func renderDoctor(r doctorReport, yes bool) {
}
}
switch {
case c.VLLMBin == "" && c.Provider != provider.VLLM:
case c.VLLMBin == "" && c.Provider != engine.VLLM:
// Not a fault: vLLM is optional once new profiles go elsewhere.
case c.VLLMBin == "":
fmt.Println(" vllm bin: NOT SET -- set VLLM_BIN in config.env")
Expand Down Expand Up @@ -789,7 +789,7 @@ func adoptService(cfg *config.Config, s detect.Server) bool {
// server is not vLLM's backend, and telling its user to install vllm-metal
// would send them after something they do not need.
func appleBackend(hw detect.Hardware, newProfiles string) string {
if hw.GPUVendor != "apple" || newProfiles != provider.VLLM {
if hw.GPUVendor != "apple" || newProfiles != engine.VLLM {
return ""
}
if !hw.Metal {
Expand Down
8 changes: 4 additions & 4 deletions internal/cli/doctor_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import (
"testing"
"time"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/detect"
"github.com/coder/vllm-helper/internal/hardware"
"github.com/coder/vllm-helper/internal/profile"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/detect"
"github.com/coder/llm-helper/internal/hardware"
"github.com/coder/llm-helper/internal/profile"
)

// Nothing in this package's tests runs in parallel: they swap os.Stdout and
Expand Down
10 changes: 5 additions & 5 deletions internal/cli/editset.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

"github.com/spf13/cobra"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/profile"
"github.com/coder/vllm-helper/internal/provider"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/engine"
"github.com/coder/llm-helper/internal/profile"
)

// standardProfileKeys are the keys every profile is expected to carry.
Expand All @@ -24,7 +24,7 @@ var standardProfileKeys = map[string]bool{
"KV_CACHE_MEMORY_BYTES": true,
"EXTRA_ARGS": true,
profile.RecipeKey: true,
provider.Key: true,
engine.Key: true,
}

func newEditCmd() *cobra.Command {
Expand Down Expand Up @@ -164,7 +164,7 @@ func validateProfile(p *profile.Profile, name string) error {
if p.Model() == "" {
return fmt.Errorf("profile '%s' has no MODEL= line -- it can't be served like this", name)
}
if _, err := provider.Lookup(p.Provider()); err != nil {
if _, err := engine.Lookup(p.Provider()); err != nil {
return fmt.Errorf("profile '%s': %w", name, err)
}
if extra := p.ExtraArgs(); extra != "" {
Expand Down
12 changes: 6 additions & 6 deletions internal/cli/engines_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/internal/nodes"
"github.com/coder/vllm-helper/internal/provider"
"github.com/coder/vllm-helper/internal/recipe"
"github.com/coder/llm-helper/internal/engine"
"github.com/coder/llm-helper/internal/nodes"
"github.com/coder/llm-helper/internal/recipe"
)

func glmRecipe(t *testing.T) recipe.TestedRecipe {
Expand Down Expand Up @@ -63,9 +63,9 @@ func TestCheckStagedNamesWhatIsMissing(t *testing.T) {
t.Fatalf("%s pins %d models into cache %q", r.ID, len(refs), cache)
}
weights, drafter := refs["weights"], refs["drafter"]
stage := func(m provider.ModelRef) {
stage := func(m engine.ModelRef) {
t.Helper()
dir := filepath.Join(home, provider.SnapshotPath(cache, m))
dir := filepath.Join(home, engine.SnapshotPath(cache, m))
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
Expand All @@ -92,7 +92,7 @@ func TestCheckStagedNamesWhatIsMissing(t *testing.T) {

// A snapshot directory with nothing in it is a download that did not
// finish.
if err := os.MkdirAll(filepath.Join(home, provider.SnapshotPath(cache, drafter)), 0o755); err != nil {
if err := os.MkdirAll(filepath.Join(home, engine.SnapshotPath(cache, drafter)), 0o755); err != nil {
t.Fatal(err)
}
if err := checkStaged(r, []recipeMember{local}, ""); err == nil || !strings.Contains(err.Error(), drafter.ID) {
Expand Down
8 changes: 4 additions & 4 deletions internal/cli/engines_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/internal/provider"
"github.com/coder/vllm-helper/internal/recipe"
"github.com/coder/llm-helper/internal/engine"
"github.com/coder/llm-helper/internal/recipe"
)

const toyEngine = `{"schema_version":1,"id":"toy","display_name":"Toy","why":"a test engine",` +
Expand All @@ -21,7 +21,7 @@ const toyEngine = `{"schema_version":1,"id":"toy","display_name":"Toy","why":"a
// named rather than taking the others with it.
func TestRunEnginesListShowsLocalDefinitions(t *testing.T) {
configDir, _ := newTree(t)
dir := filepath.Join(configDir, provider.LocalDir)
dir := filepath.Join(configDir, engine.LocalDir)
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
Expand All @@ -37,7 +37,7 @@ func TestRunEnginesListShowsLocalDefinitions(t *testing.T) {
}
// Later tests in this process must not see this directory's engines.
t.Cleanup(func() {
provider.UseLocal(filepath.Join(dir, "gone"))
engine.UseLocal(filepath.Join(dir, "gone"))
recipe.UseLocal(filepath.Join(dir, "gone"))
})

Expand Down
18 changes: 9 additions & 9 deletions internal/cli/enginescmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (

"github.com/spf13/cobra"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/provider"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/engine"
)

func newEnginesCmd() *cobra.Command {
Expand Down Expand Up @@ -62,24 +62,24 @@ func newEnginesShowCmd() *cobra.Command {

// engineRow is one engine as 'engines list --json' prints it.
type engineRow struct {
provider.Engine
engine.Engine
// Source is the engines.d file a local engine came from, or "shipped".
Source string `json:"source"`
}

func engineSource(e provider.Engine) string {
func engineSource(e engine.Engine) string {
if e.Source == "" {
return "shipped"
}
return e.Source
}

func runEnginesList(out, errOut io.Writer, jsonOut bool) error {
for _, err := range provider.LocalErrors() {
for _, err := range engine.LocalErrors() {
fmt.Fprintf(errOut, "warning: skipped a local engine definition file: %v\n", err)
}
var rows []engineRow
for _, e := range provider.Default().Engines() {
for _, e := range engine.Default().Engines() {
rows = append(rows, engineRow{Engine: e, Source: engineSource(e)})
}
if jsonOut {
Expand All @@ -93,14 +93,14 @@ func runEnginesList(out, errOut io.Writer, jsonOut bool) error {
if err := tw.Flush(); err != nil {
return err
}
fmt.Fprintf(out, "\nLocal engines go in %s.\n", filepath.Join(config.ResolveDirs().Config, provider.LocalDir))
fmt.Fprintf(out, "\nLocal engines go in %s.\n", filepath.Join(config.ResolveDirs().Config, engine.LocalDir))
return nil
}

func runEnginesShow(out io.Writer, id string, jsonOut bool) error {
e, ok := provider.Default().Get(id)
e, ok := engine.Default().Get(id)
if !ok {
return fmt.Errorf("no engine %q (have: %s)", id, strings.Join(provider.Names(), ", "))
return fmt.Errorf("no engine %q (have: %s)", id, strings.Join(engine.Names(), ", "))
}
if jsonOut {
return printJSONTo(out, engineRow{Engine: e, Source: engineSource(e)})
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/gendocs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/coder/vllm-helper/docs"
"github.com/coder/llm-helper/docs"
)

// CLIReferencePath is the manifest route whose children GenerateCLIRoutes
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/gendocs_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/docs"
"github.com/coder/llm-helper/docs"
)

// The committed reference must be exactly what the current command tree
Expand Down
4 changes: 2 additions & 2 deletions internal/cli/ggufplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

"github.com/spf13/cobra"

"github.com/coder/vllm-helper/internal/config"
"github.com/coder/vllm-helper/internal/control"
"github.com/coder/llm-helper/internal/config"
"github.com/coder/llm-helper/internal/control"
)

// ggufMissingMessage explains the gap and how to close it, naming the
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/hardware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
"testing"

"github.com/coder/vllm-helper/internal/hardware"
"github.com/coder/llm-helper/internal/hardware"
)

// A hardware.d file is loaded before every command, so 'hardware list' shows
Expand Down
Loading
Loading