Files
LocalAI/pkg/xsysinfo/cpu.go
T
localai-org-maint-botandEttore Di Giacinto 997d403de4 feat(nodes): add fleet operations dashboard (#12046)
* feat(nodes): report CPU telemetry

Assisted-by: Codex:gpt-6

* feat(nodes): add fleet view utilities

Assisted-by: Codex:gpt-6

* feat(nodes): add fleet operations dashboard

Replace the panel roster with aggregate capacity gauges, fleet filtering and selection, bounded bulk actions, and an on-demand node inspector. Extend node details and distributed-mode documentation with CPU and models-disk telemetry.

Assisted-by: Codex:gpt-6

* fix(nodes): harden fleet lifecycle actions

Assisted-by: Codex:gpt-6

* fix(nodes): restore compact fleet composition

Keep fleet health, capacity, and attention in one compact overview at ordinary desktop widths. The inspector now overlays the roster until the workbench can preserve a useful table beside it.

Assisted-by: Codex:gpt-6

* feat(nodes): add accessible running models workbench

Assisted-by: Codex:gpt-6

* fix(nodes): correct model view ARIA links

Keep each tab panel available for its controlling tab while native hidden state removes inactive content from accessibility navigation. Model controls now expose only supported state and valid inspector relationships.

Assisted-by: Codex:gpt-6

* fix(nodes): align lifecycle and capacity states

Pending nodes now expose approval wherever node actions appear, while other lifecycle controls follow the server transition rules. Capacity totals exclude incomplete readings so missing availability remains unknown.

Assisted-by: Codex:gpt-6

* fix(nodes): restore approved dashboard composition

Assisted-by: Codex:gpt-6

* fix(nodes): integrate operate navigation

Assisted-by: Codex:gpt-6

* fix(nodes): restore low density fleet view

Assisted-by: Codex:gpt-6

* fix(nodes): preserve complete operate menu

Assisted-by: Codex:gpt-6

* fix(nodes): preserve inspector workspace height

Assisted-by: Codex:gpt-6

* fix(nodes): restore standard operate navigation

Assisted-by: Codex:gpt-6

* feat(ui): add collapsible console rail

Assisted-by: Codex:gpt-6

* feat(nodes): stop models from fleet view

Assisted-by: Codex:gpt-6

* fix(nodes): make inspector a full height drawer

Assisted-by: Codex:gpt-6

* fix(model): stop mixed local and remote placements

Assisted-by: Codex:gpt-6

* fix(ui): announce action menu navigation

Assisted-by: Codex:gpt-6

* fix(nodes): keep inspector within viewport

Assisted-by: Codex:gpt-6

* fix(ui): preserve focus across model actions

Assisted-by: Codex:gpt-6

---------

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
2026-09-15 00:57:14 +02:00

85 lines
1.7 KiB
Go

package xsysinfo
import (
"fmt"
"maps"
"slices"
"sort"
"github.com/jaypipes/ghw"
"github.com/klauspost/cpuid/v2"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/load"
)
// CPUInfo describes host-wide CPU capacity and current utilization.
type CPUInfo struct {
LogicalCores uint64
UsagePercent float64
Load1 float64
}
// GetCPUInfo samples host-wide CPU telemetry.
func GetCPUInfo() (*CPUInfo, error) {
logicalCores, err := cpu.Counts(true)
if err != nil {
return nil, fmt.Errorf("counting logical CPU cores: %w", err)
}
if logicalCores < 1 {
return nil, fmt.Errorf("counting logical CPU cores: no cores reported")
}
usage, err := cpu.Percent(0, false)
if err != nil {
return nil, fmt.Errorf("sampling CPU utilization: %w", err)
}
if len(usage) != 1 {
return nil, fmt.Errorf("sampling CPU utilization: expected one aggregate reading, got %d", len(usage))
}
loadAverage, err := load.Avg()
if err != nil {
return nil, fmt.Errorf("sampling CPU load: %w", err)
}
return &CPUInfo{
LogicalCores: uint64(logicalCores),
UsagePercent: usage[0],
Load1: loadAverage.Load1,
}, nil
}
func CPUCapabilities() ([]string, error) {
cpu, err := ghw.CPU()
if err != nil {
return nil, err
}
caps := map[string]struct{}{}
for _, proc := range cpu.Processors {
for _, c := range proc.Capabilities {
caps[c] = struct{}{}
}
}
ret := slices.Collect(maps.Keys(caps))
// order
sort.Strings(ret)
return ret, nil
}
func HasCPUCaps(ids ...cpuid.FeatureID) bool {
return cpuid.CPU.Supports(ids...)
}
func CPUPhysicalCores() int {
if cpuid.CPU.PhysicalCores == 0 {
return 1
}
return cpuid.CPU.PhysicalCores
}