Monitor: show Ollama's loaded models, their VRAM footprint, and busy state
The status snapshot now queries /api/ps (2s timeout so a wedged Ollama cannot stall the channel) and the ollama line renders e.g. 'UP · llama3.1:8b (4.8 GiB VRAM) · busy'; comfy gets the busy marker too while an image job runs.
This commit is contained in:
@@ -813,7 +813,7 @@ func run(ctx context.Context, cfg config.Config, log *slog.Logger, logOut io.Wri
|
||||
// AUTO_UPDATE.
|
||||
if isService {
|
||||
serveControl(ctx, log, u, exePath, applyStaged,
|
||||
statusProvider(cfg, lk, comfySup, health, started, gw),
|
||||
statusProvider(cfg, lk, comfySup, health, started, gw, ollamaClient),
|
||||
reloadHandler(cfg, configPath, restartWhenIdle))
|
||||
}
|
||||
|
||||
@@ -1106,6 +1106,16 @@ type statusDownstream struct {
|
||||
URL string `json:"url"`
|
||||
Up bool `json:"up"`
|
||||
Managed string `json:"managed,omitempty"`
|
||||
// Models lists Ollama's loaded models with their VRAM footprint. Null
|
||||
// when unknown (query failed / not applicable); [] means none loaded —
|
||||
// deliberately no omitempty so the two stay distinguishable.
|
||||
Models []statusModel `json:"models"`
|
||||
}
|
||||
|
||||
// statusModel is one loaded Ollama model.
|
||||
type statusModel struct {
|
||||
Name string `json:"name"`
|
||||
VRAMMB int64 `json:"vram_mb"` // 0 = resident in RAM, not VRAM
|
||||
}
|
||||
|
||||
type statusLock struct {
|
||||
@@ -1183,8 +1193,10 @@ func diffConfig(a, b config.Config) []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// statusProvider assembles the one-line JSON snapshot for CmdStatus.
|
||||
func statusProvider(cfg config.Config, lk *lock.Lock, comfySup *supervise.Process, health *healthTracker, started time.Time, gw *gpuWatch) func() string {
|
||||
// statusProvider assembles the one-line JSON snapshot for CmdStatus. The
|
||||
// loaded-model query to Ollama gets a short timeout so a wedged upstream
|
||||
// cannot stall the status channel for long.
|
||||
func statusProvider(cfg config.Config, lk *lock.Lock, comfySup *supervise.Process, health *healthTracker, started time.Time, gw *gpuWatch, ollamaClient *ollama.Client) func() string {
|
||||
return func() string {
|
||||
snap := statusSnapshot{
|
||||
Version: version,
|
||||
@@ -1197,9 +1209,21 @@ func statusProvider(cfg config.Config, lk *lock.Lock, comfySup *supervise.Proces
|
||||
Foreign: foreign, AgeS: ageS,
|
||||
}
|
||||
if cfg.OllamaURL != "" {
|
||||
snap.Downstreams = append(snap.Downstreams, statusDownstream{
|
||||
d := statusDownstream{
|
||||
Name: "ollama", URL: cfg.OllamaURL, Up: health.get("ollama"),
|
||||
})
|
||||
}
|
||||
if ollamaClient != nil {
|
||||
mctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
models, err := ollamaClient.LoadedModelDetails(mctx)
|
||||
cancel()
|
||||
if err == nil {
|
||||
d.Models = make([]statusModel, 0, len(models))
|
||||
for _, m := range models {
|
||||
d.Models = append(d.Models, statusModel{Name: m.Name, VRAMMB: m.SizeVRAM / (1024 * 1024)})
|
||||
}
|
||||
}
|
||||
}
|
||||
snap.Downstreams = append(snap.Downstreams, d)
|
||||
}
|
||||
if cfg.ComfyURL != "" {
|
||||
d := statusDownstream{Name: "comfy", URL: cfg.ComfyURL, Up: health.get("comfy")}
|
||||
|
||||
Reference in New Issue
Block a user