mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-30 18:09:05 -04:00
* feat(vram): add vrambudget primitive for per-node VRAM caps Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): apply default VRAM budget in xsysinfo aggregate getters Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): wire LOCALAI_VRAM_BUDGET flag to xsysinfo default budget Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): persist VRAM budget via runtime settings with live apply Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * test(vram): reset process-global VRAM budget after runtime-settings spec Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): add VRAM budget field to Settings page Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): store and enforce per-node VRAM budget in the node registry Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): apply per-node VRAM budget in router hardware defaults Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): report worker VRAM budget in node registration The distributed worker now reports its operator-set VRAM budget string (LOCALAI_VRAM_BUDGET) to the server on registration. The worker keeps reporting RAW total/available VRAM and never sets the xsysinfo process-global budget (that stays standalone-only); the server resolves and enforces the budget uniformly (Task 6). Also closes a Task 6 gap: on re-registration, a struct Updates zero-skips an empty budget, so a worker that dropped LOCALAI_VRAM_BUDGET left the stale cap in place. For non-admin-override nodes the budget columns are now force-written (map Updates) even when empty, so removing the env var clears the cap; admin overrides are preserved unchanged. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * style(vram): drop em dash from worker-clear comment Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): add node VRAM budget admin endpoints Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): add node VRAM budget control to the node UI Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(vram): expose set_node_vram_budget MCP admin tool Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * docs(vram): document LOCALAI_VRAM_BUDGET and node VRAM budget UI Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(vram): avoid double-applying VRAM budget in GetResourceAggregateInfo The GPU-branch aggregate returned by GetResourceInfo is sourced from GetGPUAggregateInfo, which already caps total/free/used against the process-wide VRAM budget. GetResourceAggregateInfo then applied the budget a second time. For an absolute budget this is idempotent, but for a percentage budget b.Apply resolves the ceiling as a fraction of its input total, so a second pass yields P*(P*T) instead of P*T and distorts UsagePercent (read by the memory reclaimer in pkg/model/watchdog.go). Remove the redundant second application so the budget is applied exactly once, against the raw physical totals, upstream in GetGPUAggregateInfo. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(vram): implement SetNodeVRAMBudget on mcp assistant test stub The LocalAIClient interface gained SetNodeVRAMBudget; the stubClient in core/http/endpoints/mcp used by the assistant tests is a separate implementer and needs the method too (broke golangci-lint typecheck and both test jobs). Signed-off-by: Ettore Di Giacinto <mudler@localai.io> --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
49 lines
1.7 KiB
Go
49 lines
1.7 KiB
Go
package localaitools
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
)
|
|
|
|
func registerSystemTools(s *mcp.Server, client LocalAIClient, opts Options) {
|
|
mcp.AddTool(s, &mcp.Tool{
|
|
Name: ToolSystemInfo,
|
|
Description: "Report LocalAI version, paths, distributed flag, currently loaded models, and installed backends.",
|
|
}, func(ctx context.Context, _ *mcp.CallToolRequest, _ struct{}) (*mcp.CallToolResult, any, error) {
|
|
info, err := client.SystemInfo(ctx)
|
|
if err != nil {
|
|
return errorResult(err), nil, nil
|
|
}
|
|
return jsonResult(info), nil, nil
|
|
})
|
|
|
|
mcp.AddTool(s, &mcp.Tool{
|
|
Name: ToolListNodes,
|
|
Description: "List federated worker nodes (only meaningful in distributed mode; returns an empty list otherwise).",
|
|
}, func(ctx context.Context, _ *mcp.CallToolRequest, _ struct{}) (*mcp.CallToolResult, any, error) {
|
|
nodes, err := client.ListNodes(ctx)
|
|
if err != nil {
|
|
return errorResult(err), nil, nil
|
|
}
|
|
return jsonResult(nodes), nil, nil
|
|
})
|
|
|
|
if opts.DisableMutating {
|
|
return
|
|
}
|
|
|
|
mcp.AddTool(s, &mcp.Tool{
|
|
Name: ToolSetNodeVRAMBudget,
|
|
Description: "Set a federated node's VRAM allocation budget (\"80%\" or \"12GB\"; empty clears the override). Only meaningful in distributed mode. Requires user confirmation per safety rule 1.",
|
|
}, func(ctx context.Context, _ *mcp.CallToolRequest, args SetNodeVRAMBudgetRequest) (*mcp.CallToolResult, any, error) {
|
|
if args.NodeID == "" {
|
|
return errorResultf("node_id is required"), nil, nil
|
|
}
|
|
if err := client.SetNodeVRAMBudget(ctx, args.NodeID, args.Budget); err != nil {
|
|
return errorResult(err), nil, nil
|
|
}
|
|
return jsonResult(map[string]string{"node_id": args.NodeID, "vram_budget": args.Budget}), nil, nil
|
|
})
|
|
}
|