From 768c73889e62acf5f627e42b7d918fe0effefdcd Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Tue, 18 Aug 2026 11:49:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20webui=20chat=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AE=BE=E5=A4=87=E8=BA=AB=E4=BB=BD(device?= =?UTF-8?q?=5Fid/device=5Fname)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - handleChat body 增加 device_id/device_name 可选字段 - 来源编码: 带设备时 webui/{device_id}(agent 可见来源), 无设备保持 webui(兼容) - injectSourceContext: 检测 device_id 时注入「当前输入来自设备[名](id)」上下文 - 验证: 带 device_id=gui-pc-002 消息 agent 正确回答来源客厅电脑; 无 device_id 兼容 --- internal/agent/core/stage.go | 8 ++++++++ internal/plugins/webui/handler.go | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/agent/core/stage.go b/internal/agent/core/stage.go index 005913f..dda837b 100644 --- a/internal/agent/core/stage.go +++ b/internal/agent/core/stage.go @@ -70,6 +70,14 @@ func (a *Agent) injectSourceContext(stageCtx *sdk.StageContext, evt *agentIO.Inp channel = source } content := fmt.Sprintf("当前输入来源: %s;默认输出通道: %s。", source, channel) + // 来源含设备身份(webui/{device_id})时补充设备名,便于 agent 区分多设备输入 + if devID, _ := evt.Payload["device_id"].(string); devID != "" { + devName, _ := evt.Payload["device_name"].(string) + if devName == "" { + devName = devID + } + content = fmt.Sprintf("当前输入来自设备[%s](%s);默认输出通道: %s。", devName, devID, channel) + } if flag, _ := evt.Payload["interrupt"].(bool); flag { content = fmt.Sprintf("这是一条打断输入。来源: %s;默认输出通道: %s。", source, channel) } diff --git a/internal/plugins/webui/handler.go b/internal/plugins/webui/handler.go index 28c822c..be49aac 100644 --- a/internal/plugins/webui/handler.go +++ b/internal/plugins/webui/handler.go @@ -1159,7 +1159,9 @@ func (h *Handler) handleChat(w http.ResponseWriter, r *http.Request) { return } var body struct { - Message string `json:"message"` + Message string `json:"message"` + DeviceID string `json:"device_id"` // 消息来源设备(GUI/受控设备),可选 + DeviceName string `json:"device_name"` // 设备显示名,可选 } if err := json.NewDecoder(r.Body).Decode(&body); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid json"}) @@ -1174,13 +1176,24 @@ func (h *Handler) handleChat(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "agent unavailable"}) return } + // 来源编码:带设备身份时用 webui/{device_id}(agent 经 injectSourceContext 可见来源); + // 无设备时保持 webui(兼容旧调用)。device_name 一并注入便于 agent 识别。 + source := "webui" + if body.DeviceID != "" { + source = "webui/" + body.DeviceID + } + payload := map[string]interface{}{"content": body.Message} + if body.DeviceID != "" { + payload["device_id"] = body.DeviceID + payload["device_name"] = body.DeviceName + } // 带超时的上下文,防止 InjectTextSync 长时间阻塞 HTTP 请求 ctx, cancel := context.WithTimeout(r.Context(), 60*time.Second) defer cancel() respCh := make(chan *agentIO.OutputEvent, 1) go func() { - respCh <- h.sdk.InjectTextSync("webui", "webui", body.Message) + respCh <- h.sdk.InjectInputSync(source, "webui", "text", payload) }() var resp *agentIO.OutputEvent