feat(todo): 实现待办事项列表的动态刷新和状态管理

- 在 runtime 中为待办事项添加基于系统时间的时间戳
- 修复前端 TodoPanel 组件的数据刷新逻辑
- 添加 setTodos 状态更新函数以支持待办事项清空操作
- 实现根据当前视图动态选择请求命令的功能
- 优化待办事项数据的过滤和映射处理流程
This commit is contained in:
oudecheng 2026-06-15 16:20:40 +08:00
parent 7626ba2d2f
commit 027e8661bc
3 changed files with 24 additions and 7 deletions

View File

@ -211,9 +211,15 @@ impl SubAgentEmitter {
let scope_key = &self.sub_session_id; let scope_key = &self.sub_session_id;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs() as i64;
let records: Vec<crate::storage::TodoRecord> = todos_array let records: Vec<crate::storage::TodoRecord> = todos_array
.iter() .iter()
.filter_map(|item| { .enumerate()
.filter_map(|(idx, item)| {
Some(crate::storage::TodoRecord { Some(crate::storage::TodoRecord {
id: item.get("id")?.as_str()?.to_string(), id: item.get("id")?.as_str()?.to_string(),
scope_key: scope_key.clone(), scope_key: scope_key.clone(),
@ -221,9 +227,9 @@ impl SubAgentEmitter {
topic_id: None, topic_id: None,
content: item.get("content")?.as_str()?.to_string(), content: item.get("content")?.as_str()?.to_string(),
status: item.get("status")?.as_str()?.to_string(), status: item.get("status")?.as_str()?.to_string(),
priority: item.get("priority")?.as_str()?.to_string(), priority: "medium".to_string(),
created_at: item.get("created_at")?.as_i64()?, created_at: now + idx as i64,
updated_at: item.get("updated_at")?.as_i64()?, updated_at: now,
}) })
}) })
.collect(); .collect();

View File

@ -49,6 +49,7 @@ function App() {
skills, skills,
requestSkillList, requestSkillList,
todos, todos,
setTodos,
requestTodoList, requestTodoList,
requestSubAgentTodoList, requestSubAgentTodoList,
// 定时任务 // 定时任务
@ -355,12 +356,13 @@ function App() {
const key = `${selectedTopic ?? ''}|${subAgentView?.taskId ?? ''}` const key = `${selectedTopic ?? ''}|${subAgentView?.taskId ?? ''}`
if (key === prevTodoTriggerRef.current) return if (key === prevTodoTriggerRef.current) return
prevTodoTriggerRef.current = key prevTodoTriggerRef.current = key
setTodos([]) // 先清空,防止切换时短暂显示旧 scope 的 todos
const todoCmd = subAgentView?.taskId const todoCmd = subAgentView?.taskId
? requestSubAgentTodoList(subAgentView.taskId) ? requestSubAgentTodoList(subAgentView.taskId)
: requestTodoList() : requestTodoList()
handleCommand(todoCmd) handleCommand(todoCmd)
sendMessage({ type: 'command', payload: JSON.stringify(todoCmd) }) sendMessage({ type: 'command', payload: JSON.stringify(todoCmd) })
}, [status, selectedTopic, subAgentView, handleCommand, sendMessage, requestTodoList, requestSubAgentTodoList]) }, [status, selectedTopic, subAgentView, handleCommand, sendMessage, requestTodoList, requestSubAgentTodoList, setTodos])
const handleRefreshMemories = useCallback(() => { const handleRefreshMemories = useCallback(() => {
const cmd = requestMemoryList() const cmd = requestMemoryList()
@ -379,6 +381,13 @@ function App() {
sendMessage({ type: 'command', payload: JSON.stringify(cmd) }) sendMessage({ type: 'command', payload: JSON.stringify(cmd) })
}, [handleCommand, sendMessage]) }, [handleCommand, sendMessage])
// 根据当前视图(主会话/子代理)返回正确的 todo 请求命令
const refreshTodoList = useCallback((): Command => {
return subAgentView?.taskId
? requestSubAgentTodoList(subAgentView.taskId)
: requestTodoList()
}, [subAgentView, requestTodoList, requestSubAgentTodoList])
const handleRefreshSchedulerJobs = useCallback(() => { const handleRefreshSchedulerJobs = useCallback(() => {
const cmd = requestSchedulerJobList() const cmd = requestSchedulerJobList()
handleCommand(cmd) handleCommand(cmd)
@ -719,7 +728,7 @@ function App() {
{/* 悬浮 Todo 面板 */} {/* 悬浮 Todo 面板 */}
<TodoPanel <TodoPanel
todos={todos} todos={todos}
requestTodoList={requestTodoList} requestTodoList={refreshTodoList}
sendCommand={sendMemoryCommand} sendCommand={sendMemoryCommand}
/> />

View File

@ -1,4 +1,4 @@
import { useState, useCallback, useEffect, useRef, useMemo } from 'react' import { useState, useCallback, useEffect, useRef, useMemo, type Dispatch, type SetStateAction } from 'react'
import type { import type {
Command, Command,
ChatMessage, ChatMessage,
@ -98,6 +98,7 @@ interface UseChatReturn {
// Todo 状态 // Todo 状态
todos: TodoItemSummary[] todos: TodoItemSummary[]
setTodos: Dispatch<SetStateAction<TodoItemSummary[]>>
requestTodoList: () => Command requestTodoList: () => Command
requestSubAgentTodoList: (subTaskId: string) => Command requestSubAgentTodoList: (subTaskId: string) => Command
@ -957,6 +958,7 @@ export function useChat(): UseChatReturn {
skills, skills,
requestSkillList, requestSkillList,
todos, todos,
setTodos,
requestTodoList, requestTodoList,
requestSubAgentTodoList, requestSubAgentTodoList,
schedulerJobs, schedulerJobs,