feat: 添加 topic_id 字段到消息结构,优化消息处理逻辑
This commit is contained in:
parent
87fc8cc3b7
commit
cedd8b2a69
@ -202,6 +202,8 @@ pub enum WsOutbound {
|
|||||||
task_id: String,
|
task_id: String,
|
||||||
description: String,
|
description: String,
|
||||||
subagent_type: String,
|
subagent_type: String,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
topic_id: Option<String>,
|
||||||
},
|
},
|
||||||
#[serde(rename = "session_established")]
|
#[serde(rename = "session_established")]
|
||||||
SessionEstablished { session_id: String },
|
SessionEstablished { session_id: String },
|
||||||
|
|||||||
@ -172,6 +172,7 @@ pub(crate) fn ws_outbound_from_outbound_message(message: &OutboundMessage) -> Ve
|
|||||||
task_id: message.metadata.get("task_id").cloned().unwrap_or_default(),
|
task_id: message.metadata.get("task_id").cloned().unwrap_or_default(),
|
||||||
description: message.metadata.get("task_description").cloned().unwrap_or_default(),
|
description: message.metadata.get("task_description").cloned().unwrap_or_default(),
|
||||||
subagent_type: message.metadata.get("task_subagent_type").cloned().unwrap_or_default(),
|
subagent_type: message.metadata.get("task_subagent_type").cloned().unwrap_or_default(),
|
||||||
|
topic_id: message.metadata.get("topic_id").cloned(),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -250,6 +250,7 @@ impl DefaultSubAgentRuntime {
|
|||||||
let mut metadata = HashMap::new();
|
let mut metadata = HashMap::new();
|
||||||
metadata.insert("subagent_task_id".to_string(), session.id.clone());
|
metadata.insert("subagent_task_id".to_string(), session.id.clone());
|
||||||
metadata.insert("is_subagent_event".to_string(), "true".to_string());
|
metadata.insert("is_subagent_event".to_string(), "true".to_string());
|
||||||
|
metadata.insert("topic_id".to_string(), session.parent_topic_id.clone().unwrap_or_default());
|
||||||
|
|
||||||
let emitter = Arc::new(PersistingEmittedMessageHandler::new(
|
let emitter = Arc::new(PersistingEmittedMessageHandler::new(
|
||||||
SubAgentEmitter {
|
SubAgentEmitter {
|
||||||
@ -424,6 +425,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
metadata.insert("task_id".to_string(), session.id.clone());
|
metadata.insert("task_id".to_string(), session.id.clone());
|
||||||
metadata.insert("task_description".to_string(), session.description.clone());
|
metadata.insert("task_description".to_string(), session.description.clone());
|
||||||
metadata.insert("task_subagent_type".to_string(), session.subagent_type.clone());
|
metadata.insert("task_subagent_type".to_string(), session.subagent_type.clone());
|
||||||
|
metadata.insert("topic_id".to_string(), session.parent_topic_id.clone().unwrap_or_default());
|
||||||
|
|
||||||
let event = OutboundMessage {
|
let event = OutboundMessage {
|
||||||
channel: session.parent_channel_name.clone(),
|
channel: session.parent_channel_name.clone(),
|
||||||
|
|||||||
@ -181,6 +181,15 @@ export function useChat(): UseChatReturn {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract topic_id from a message if present
|
||||||
|
const getTopicId = (message: WsOutbound): string | undefined => {
|
||||||
|
if (message.type === 'tool_call' || message.type === 'tool_result'
|
||||||
|
|| message.type === 'tool_pending' || message.type === 'assistant_response') {
|
||||||
|
return (message as ToolCall | ToolResult | ToolPending | AssistantResponse).topic_id
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a server message to ChatMessage (extracted from handleServerMessage logic)
|
// Convert a server message to ChatMessage (extracted from handleServerMessage logic)
|
||||||
const serverMessageToChatMessage = (message: WsOutbound): ChatMessage | null => {
|
const serverMessageToChatMessage = (message: WsOutbound): ChatMessage | null => {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
@ -311,12 +320,20 @@ export function useChat(): UseChatReturn {
|
|||||||
appendToSubAgentViewMessage(message)
|
appendToSubAgentViewMessage(message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 丢弃其他子智能体的消息,避免 fall through 到主消息处理
|
||||||
|
if (msgSubagentTaskId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In main view, skip sub-agent messages (they belong to sub-agent view).
|
// In main view, skip sub-agent messages (they belong to sub-agent view).
|
||||||
// But use the task_id to associate with the running task tool card.
|
// But use the task_id to associate with the running task tool card.
|
||||||
const msgSubagentTaskId = getSubagentTaskId(message)
|
const msgSubagentTaskId = getSubagentTaskId(message)
|
||||||
if (msgSubagentTaskId) {
|
if (msgSubagentTaskId) {
|
||||||
|
// 只 backfill 当前话题的 task tool_call,避免跨话题串扰
|
||||||
|
const msgTopicId = getTopicId(message)
|
||||||
|
if (msgTopicId && msgTopicId !== selectedTopicRef.current) return
|
||||||
|
|
||||||
setMessages((prev) => {
|
setMessages((prev) => {
|
||||||
for (let i = prev.length - 1; i >= 0; i--) {
|
for (let i = prev.length - 1; i >= 0; i--) {
|
||||||
if (prev[i].type === 'tool_call' && prev[i].toolName === 'task' && !prev[i].subagentTaskId) {
|
if (prev[i].type === 'tool_call' && prev[i].toolName === 'task' && !prev[i].subagentTaskId) {
|
||||||
@ -340,6 +357,9 @@ export function useChat(): UseChatReturn {
|
|||||||
|
|
||||||
case 'task_started': {
|
case 'task_started': {
|
||||||
const msg = message as TaskStarted
|
const msg = message as TaskStarted
|
||||||
|
// 只 backfill 当前话题的 task tool_call,避免跨话题串扰
|
||||||
|
if (msg.topic_id && msg.topic_id !== selectedTopicRef.current) break
|
||||||
|
|
||||||
// 立即更新对应的 task tool_call,让用户可以点击查看实时进度
|
// 立即更新对应的 task tool_call,让用户可以点击查看实时进度
|
||||||
setMessages((prev) => {
|
setMessages((prev) => {
|
||||||
for (let i = prev.length - 1; i >= 0; i--) {
|
for (let i = prev.length - 1; i >= 0; i--) {
|
||||||
@ -602,6 +622,7 @@ export function useChat(): UseChatReturn {
|
|||||||
const selectTopic = useCallback((topicId: string) => {
|
const selectTopic = useCallback((topicId: string) => {
|
||||||
setSelectedTopic(topicId)
|
setSelectedTopic(topicId)
|
||||||
setMessages([])
|
setMessages([])
|
||||||
|
setSubAgentView(null)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const createTopic = useCallback((title?: string): Command => {
|
const createTopic = useCallback((title?: string): Command => {
|
||||||
@ -647,6 +668,7 @@ export function useChat(): UseChatReturn {
|
|||||||
setTopics([])
|
setTopics([])
|
||||||
setSelectedTopic(null)
|
setSelectedTopic(null)
|
||||||
setMessages([])
|
setMessages([])
|
||||||
|
setSubAgentView(null)
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
}, [selectedChannel])
|
}, [selectedChannel])
|
||||||
|
|
||||||
@ -656,6 +678,7 @@ export function useChat(): UseChatReturn {
|
|||||||
setTopics([])
|
setTopics([])
|
||||||
setSelectedTopic(null)
|
setSelectedTopic(null)
|
||||||
setMessages([])
|
setMessages([])
|
||||||
|
setSubAgentView(null)
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
}, [selectedSessionId])
|
}, [selectedSessionId])
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,7 @@ export interface TaskStarted {
|
|||||||
task_id: string
|
task_id: string
|
||||||
description: string
|
description: string
|
||||||
subagent_type: string
|
subagent_type: string
|
||||||
|
topic_id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SessionEstablished {
|
export interface SessionEstablished {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user