backend: add unified restart-required signature logic
- Add bootConfigSignature to gateway state for tracking restart-sensitive config - Implement computeConfigSignature() to capture model and tool enabled states - Add gatewayRestartRequiredBySignature() for unified restart detection - Update gatewayStatusData() to use signature-based comparison - Preserve backward compatibility with existing boot_default_model field
This commit is contained in:
parent
5f50ae5e76
commit
538415bca5
1 changed files with 108 additions and 12 deletions
|
|
@ -29,6 +29,7 @@ var gateway = struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
owned bool // true if we started the process, false if we attached to an existing one
|
owned bool // true if we started the process, false if we attached to an existing one
|
||||||
bootDefaultModel string
|
bootDefaultModel string
|
||||||
|
bootConfigSignature string
|
||||||
runtimeStatus string
|
runtimeStatus string
|
||||||
startupDeadline time.Time
|
startupDeadline time.Time
|
||||||
logs *LogBuffer
|
logs *LogBuffer
|
||||||
|
|
@ -187,6 +188,95 @@ func gatewayRestartRequired(configDefaultModel, bootDefaultModel, gatewayStatus
|
||||||
return configDefaultModel != bootDefaultModel
|
return configDefaultModel != bootDefaultModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func computeConfigSignature(cfg *config.Config) string {
|
||||||
|
if cfg == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var parts []string
|
||||||
|
defaultModel := strings.TrimSpace(cfg.Agents.Defaults.GetModelName())
|
||||||
|
if defaultModel != "" {
|
||||||
|
parts = append(parts, "model:"+defaultModel)
|
||||||
|
}
|
||||||
|
toolSignatures := []string{}
|
||||||
|
if cfg.Tools.ReadFile.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "read_file")
|
||||||
|
}
|
||||||
|
if cfg.Tools.WriteFile.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "write_file")
|
||||||
|
}
|
||||||
|
if cfg.Tools.ListDir.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "list_dir")
|
||||||
|
}
|
||||||
|
if cfg.Tools.EditFile.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "edit_file")
|
||||||
|
}
|
||||||
|
if cfg.Tools.AppendFile.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "append_file")
|
||||||
|
}
|
||||||
|
if cfg.Tools.Exec.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "exec")
|
||||||
|
}
|
||||||
|
if cfg.Tools.Cron.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "cron")
|
||||||
|
}
|
||||||
|
if cfg.Tools.Web.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "web")
|
||||||
|
}
|
||||||
|
if cfg.Tools.WebFetch.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "web_fetch")
|
||||||
|
}
|
||||||
|
if cfg.Tools.Message.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "message")
|
||||||
|
}
|
||||||
|
if cfg.Tools.SendFile.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "send_file")
|
||||||
|
}
|
||||||
|
if cfg.Tools.FindSkills.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "find_skills")
|
||||||
|
}
|
||||||
|
if cfg.Tools.InstallSkill.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "install_skill")
|
||||||
|
}
|
||||||
|
if cfg.Tools.Spawn.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "spawn")
|
||||||
|
}
|
||||||
|
if cfg.Tools.SpawnStatus.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "spawn_status")
|
||||||
|
}
|
||||||
|
if cfg.Tools.I2C.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "i2c")
|
||||||
|
}
|
||||||
|
if cfg.Tools.SPI.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "spi")
|
||||||
|
}
|
||||||
|
if cfg.Tools.MCP.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "mcp")
|
||||||
|
}
|
||||||
|
if cfg.Tools.MCP.Discovery.Enabled {
|
||||||
|
toolSignatures = append(toolSignatures, "mcp_discovery")
|
||||||
|
}
|
||||||
|
if cfg.Tools.MCP.Discovery.UseRegex {
|
||||||
|
toolSignatures = append(toolSignatures, "mcp_discovery_regex")
|
||||||
|
}
|
||||||
|
if cfg.Tools.MCP.Discovery.UseBM25 {
|
||||||
|
toolSignatures = append(toolSignatures, "mcp_discovery_bm25")
|
||||||
|
}
|
||||||
|
if len(toolSignatures) > 0 {
|
||||||
|
parts = append(parts, "tools:"+strings.Join(toolSignatures, ","))
|
||||||
|
}
|
||||||
|
return strings.Join(parts, ";")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gatewayRestartRequiredBySignature(bootSignature, currentSignature, gatewayStatus string) bool {
|
||||||
|
if gatewayStatus != "running" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if bootSignature == "" || currentSignature == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bootSignature != currentSignature
|
||||||
|
}
|
||||||
|
|
||||||
func isCmdProcessAliveLocked(cmd *exec.Cmd) bool {
|
func isCmdProcessAliveLocked(cmd *exec.Cmd) bool {
|
||||||
if cmd == nil || cmd.Process == nil {
|
if cmd == nil || cmd.Process == nil {
|
||||||
return false
|
return false
|
||||||
|
|
@ -228,10 +318,11 @@ func attachToGatewayProcessLocked(pid int, cfg *config.Config) error {
|
||||||
gateway.owned = false // We didn't start this process
|
gateway.owned = false // We didn't start this process
|
||||||
setGatewayRuntimeStatusLocked("running")
|
setGatewayRuntimeStatusLocked("running")
|
||||||
|
|
||||||
// Update bootDefaultModel from config
|
// Update bootDefaultModel and bootConfigSignature from config
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
defaultModelName := strings.TrimSpace(cfg.Agents.Defaults.GetModelName())
|
defaultModelName := strings.TrimSpace(cfg.Agents.Defaults.GetModelName())
|
||||||
gateway.bootDefaultModel = defaultModelName
|
gateway.bootDefaultModel = defaultModelName
|
||||||
|
gateway.bootConfigSignature = computeConfigSignature(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.InfoC("gateway", fmt.Sprintf("Attached to gateway process (PID: %d)", pid))
|
logger.InfoC("gateway", fmt.Sprintf("Attached to gateway process (PID: %d)", pid))
|
||||||
|
|
@ -419,6 +510,7 @@ func (h *Handler) startGatewayLocked(initialStatus string, existingPid int) (int
|
||||||
gateway.cmd = cmd
|
gateway.cmd = cmd
|
||||||
gateway.owned = true // We started this process
|
gateway.owned = true // We started this process
|
||||||
gateway.bootDefaultModel = defaultModelName
|
gateway.bootDefaultModel = defaultModelName
|
||||||
|
gateway.bootConfigSignature = computeConfigSignature(cfg)
|
||||||
setGatewayRuntimeStatusLocked(initialStatus)
|
setGatewayRuntimeStatusLocked(initialStatus)
|
||||||
pid = cmd.Process.Pid
|
pid = cmd.Process.Pid
|
||||||
logger.InfoC("gateway", fmt.Sprintf("Started picoclaw gateway (PID: %d) from %s", pid, execPath))
|
logger.InfoC("gateway", fmt.Sprintf("Started picoclaw gateway (PID: %d) from %s", pid, execPath))
|
||||||
|
|
@ -439,6 +531,7 @@ func (h *Handler) startGatewayLocked(initialStatus string, existingPid int) (int
|
||||||
if gateway.cmd == cmd {
|
if gateway.cmd == cmd {
|
||||||
gateway.cmd = nil
|
gateway.cmd = nil
|
||||||
gateway.bootDefaultModel = ""
|
gateway.bootDefaultModel = ""
|
||||||
|
gateway.bootConfigSignature = ""
|
||||||
if gateway.runtimeStatus != "restarting" {
|
if gateway.runtimeStatus != "restarting" {
|
||||||
setGatewayRuntimeStatusLocked("stopped")
|
setGatewayRuntimeStatusLocked("stopped")
|
||||||
}
|
}
|
||||||
|
|
@ -784,11 +877,14 @@ func (h *Handler) gatewayStatusData() map[string]any {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bootDefaultModel, _ := data["boot_default_model"].(string)
|
|
||||||
gatewayStatus, _ := data["gateway_status"].(string)
|
gatewayStatus, _ := data["gateway_status"].(string)
|
||||||
data["gateway_restart_required"] = gatewayRestartRequired(
|
currentConfigSignature := computeConfigSignature(cfg)
|
||||||
configDefaultModel,
|
gateway.mu.Lock()
|
||||||
bootDefaultModel,
|
bootConfigSignature := gateway.bootConfigSignature
|
||||||
|
gateway.mu.Unlock()
|
||||||
|
data["gateway_restart_required"] = gatewayRestartRequiredBySignature(
|
||||||
|
bootConfigSignature,
|
||||||
|
currentConfigSignature,
|
||||||
gatewayStatus,
|
gatewayStatus,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue