fix(gateway): guard startup info assertions
This commit is contained in:
parent
1260fd8e2f
commit
36d72a0112
2 changed files with 140 additions and 11 deletions
|
|
@ -205,18 +205,11 @@ func Run(debug bool, homePath, configPath string, allowEmptyStartup bool) (runEr
|
||||||
publishGatewayEvent(agentLoop, runtimeevents.KindGatewayStart, startedAt, nil)
|
publishGatewayEvent(agentLoop, runtimeevents.KindGatewayStart, startedAt, nil)
|
||||||
|
|
||||||
fmt.Println("\n📦 Agent Status:")
|
fmt.Println("\n📦 Agent Status:")
|
||||||
startupInfo := agentLoop.GetStartupInfo()
|
startupStatus := collectGatewayStartupStatus(agentLoop.GetStartupInfo())
|
||||||
toolsInfo := startupInfo["tools"].(map[string]any)
|
fmt.Printf(" • Tools: %d loaded\n", startupStatus.toolsCount)
|
||||||
skillsInfo := startupInfo["skills"].(map[string]any)
|
fmt.Printf(" • Skills: %d/%d available\n", startupStatus.skillsAvailable, startupStatus.skillsTotal)
|
||||||
fmt.Printf(" • Tools: %d loaded\n", toolsInfo["count"])
|
|
||||||
fmt.Printf(" • Skills: %d/%d available\n", skillsInfo["available"], skillsInfo["total"])
|
|
||||||
|
|
||||||
logger.InfoCF("agent", "Agent initialized",
|
logger.InfoCF("agent", "Agent initialized", startupStatus.logFields)
|
||||||
map[string]any{
|
|
||||||
"tools_count": toolsInfo["count"],
|
|
||||||
"skills_total": skillsInfo["total"],
|
|
||||||
"skills_available": skillsInfo["available"],
|
|
||||||
})
|
|
||||||
|
|
||||||
runningServices, err := setupAndStartServices(cfg, agentLoop, msgBus, pidData.Token, listenResult)
|
runningServices, err := setupAndStartServices(cfg, agentLoop, msgBus, pidData.Token, listenResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -315,6 +308,54 @@ func preCheckConfig(cfg *config.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type gatewayStartupStatus struct {
|
||||||
|
toolsCount int
|
||||||
|
skillsAvailable int
|
||||||
|
skillsTotal int
|
||||||
|
logFields map[string]any
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectGatewayStartupStatus(startupInfo map[string]any) gatewayStartupStatus {
|
||||||
|
status := gatewayStartupStatus{logFields: map[string]any{}}
|
||||||
|
|
||||||
|
if toolsInfo, ok := startupInfo["tools"].(map[string]any); ok {
|
||||||
|
if count, ok := startupInfoInt(toolsInfo["count"]); ok {
|
||||||
|
status.toolsCount = count
|
||||||
|
status.logFields["tools_count"] = count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if skillsInfo, ok := startupInfo["skills"].(map[string]any); ok {
|
||||||
|
if total, ok := startupInfoInt(skillsInfo["total"]); ok {
|
||||||
|
status.skillsTotal = total
|
||||||
|
status.logFields["skills_total"] = total
|
||||||
|
}
|
||||||
|
if available, ok := startupInfoInt(skillsInfo["available"]); ok {
|
||||||
|
status.skillsAvailable = available
|
||||||
|
status.logFields["skills_available"] = available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
func startupInfoInt(value any) (int, bool) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case int:
|
||||||
|
return v, true
|
||||||
|
case int32:
|
||||||
|
return int(v), true
|
||||||
|
case int64:
|
||||||
|
return int(v), true
|
||||||
|
case float32:
|
||||||
|
return int(v), true
|
||||||
|
case float64:
|
||||||
|
return int(v), true
|
||||||
|
default:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func executeReload(
|
func executeReload(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
agentLoop *agent.AgentLoop,
|
agentLoop *agent.AgentLoop,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -113,6 +114,93 @@ func TestGatewayRunStartupFailureHelper(t *testing.T) {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCollectGatewayStartupStatusHandlesMalformedInfo(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
startupInfo map[string]any
|
||||||
|
wantToolsCount int
|
||||||
|
wantSkillsAvailable int
|
||||||
|
wantSkillsTotal int
|
||||||
|
wantLogFields map[string]any
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "missing info",
|
||||||
|
startupInfo: map[string]any{},
|
||||||
|
wantLogFields: map[string]any{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong map shapes",
|
||||||
|
startupInfo: map[string]any{
|
||||||
|
"tools": "unexpected",
|
||||||
|
"skills": []any{"unexpected"},
|
||||||
|
},
|
||||||
|
wantLogFields: map[string]any{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid startup info",
|
||||||
|
startupInfo: map[string]any{
|
||||||
|
"tools": map[string]any{
|
||||||
|
"count": 3,
|
||||||
|
},
|
||||||
|
"skills": map[string]any{
|
||||||
|
"available": 2,
|
||||||
|
"total": 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantToolsCount: 3,
|
||||||
|
wantSkillsAvailable: 2,
|
||||||
|
wantSkillsTotal: 5,
|
||||||
|
wantLogFields: map[string]any{
|
||||||
|
"tools_count": 3,
|
||||||
|
"skills_available": 2,
|
||||||
|
"skills_total": 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "json number startup info",
|
||||||
|
startupInfo: map[string]any{
|
||||||
|
"tools": map[string]any{
|
||||||
|
"count": float64(4),
|
||||||
|
},
|
||||||
|
"skills": map[string]any{
|
||||||
|
"available": float64(1),
|
||||||
|
"total": float64(6),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantToolsCount: 4,
|
||||||
|
wantSkillsAvailable: 1,
|
||||||
|
wantSkillsTotal: 6,
|
||||||
|
wantLogFields: map[string]any{
|
||||||
|
"tools_count": 4,
|
||||||
|
"skills_available": 1,
|
||||||
|
"skills_total": 6,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
got := collectGatewayStartupStatus(tt.startupInfo)
|
||||||
|
if got.toolsCount != tt.wantToolsCount {
|
||||||
|
t.Fatalf("toolsCount = %d, want %d", got.toolsCount, tt.wantToolsCount)
|
||||||
|
}
|
||||||
|
if got.skillsAvailable != tt.wantSkillsAvailable {
|
||||||
|
t.Fatalf("skillsAvailable = %d, want %d", got.skillsAvailable, tt.wantSkillsAvailable)
|
||||||
|
}
|
||||||
|
if got.skillsTotal != tt.wantSkillsTotal {
|
||||||
|
t.Fatalf("skillsTotal = %d, want %d", got.skillsTotal, tt.wantSkillsTotal)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got.logFields, tt.wantLogFields) {
|
||||||
|
t.Fatalf("logFields = %#v, want %#v", got.logFields, tt.wantLogFields)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPublishGatewayEvent(t *testing.T) {
|
func TestPublishGatewayEvent(t *testing.T) {
|
||||||
eventBus := runtimeevents.NewBus()
|
eventBus := runtimeevents.NewBus()
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue