|
|
@@ -282,6 +282,26 @@ func printConfigUsage() {
|
|
|
}
|
|
|
|
|
|
func createCallback(mqttClient *mqttcli.Client, apiServer *api.Server) monitor.EventCallback {
|
|
|
+ lastStatus := make(map[int]string)
|
|
|
+ var mu sync.Mutex
|
|
|
+
|
|
|
+ publish := func(port int, status string, code string) {
|
|
|
+ if mqttClient != nil {
|
|
|
+ payload := map[string]interface{}{
|
|
|
+ "port": port,
|
|
|
+ "status": status,
|
|
|
+ "code": code,
|
|
|
+ "timestamp": time.Now().Format(time.RFC3339),
|
|
|
+ }
|
|
|
+ if err := mqttClient.PublishRaw(mqttClient.GetTopic(), payload); err != nil {
|
|
|
+ fmt.Printf("MQTT 发送失败: %v\n", err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if apiServer != nil {
|
|
|
+ apiServer.BroadcastStatus(port, status, code)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return func(port int, evt *event.SSEEvent) {
|
|
|
msg := event.FormatEvent(port, evt)
|
|
|
if msg != "" {
|
|
|
@@ -292,49 +312,55 @@ func createCallback(mqttClient *mqttcli.Client, apiServer *api.Server) monitor.E
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- var status string
|
|
|
+ var status, code string
|
|
|
|
|
|
switch evt.Type {
|
|
|
case "session.status":
|
|
|
if s, ok := evt.Properties["status"].(map[string]interface{}); ok {
|
|
|
+ if t, ok := s["type"].(string); ok {
|
|
|
+ code = t
|
|
|
+ }
|
|
|
status = event.ParseStatus(s)
|
|
|
}
|
|
|
case "session.idle":
|
|
|
status = "空闲"
|
|
|
+ code = "idle"
|
|
|
case "message.part.updated":
|
|
|
if part, ok := evt.Properties["part"].(map[string]interface{}); ok {
|
|
|
switch part["type"].(string) {
|
|
|
case "tool":
|
|
|
if st, ok := part["state"].(map[string]interface{}); ok {
|
|
|
+ if s, ok := st["status"].(string); ok {
|
|
|
+ code = s
|
|
|
+ }
|
|
|
status = event.ParseToolState(st)
|
|
|
}
|
|
|
case "reasoning":
|
|
|
status = "思考中"
|
|
|
+ code = "reasoning"
|
|
|
default:
|
|
|
status = "使用工具中"
|
|
|
+ code = "using_tool"
|
|
|
}
|
|
|
}
|
|
|
case "permission.updated":
|
|
|
status = "等待权限"
|
|
|
+ code = "permission"
|
|
|
case "session.error":
|
|
|
status = "错误"
|
|
|
+ code = "error"
|
|
|
}
|
|
|
|
|
|
if status != "" {
|
|
|
- if mqttClient != nil {
|
|
|
- payload := map[string]interface{}{
|
|
|
- "port": port,
|
|
|
- "status": status,
|
|
|
- "timestamp": time.Now().Format(time.RFC3339),
|
|
|
- }
|
|
|
- if err := mqttClient.PublishRaw(mqttClient.GetTopic(), payload); err != nil {
|
|
|
- fmt.Printf("MQTT 发送失败: %v\n", err)
|
|
|
- }
|
|
|
+ mu.Lock()
|
|
|
+ prev := lastStatus[port]
|
|
|
+ if status == "空闲" && prev != "" && prev != "空闲" {
|
|
|
+ publish(port, "会话完成", "session_completed")
|
|
|
}
|
|
|
+ lastStatus[port] = status
|
|
|
+ mu.Unlock()
|
|
|
|
|
|
- if apiServer != nil {
|
|
|
- apiServer.BroadcastStatus(port, status)
|
|
|
- }
|
|
|
+ publish(port, status, code)
|
|
|
}
|
|
|
}
|
|
|
}
|