diff --git a/web/src/components/AgentPopover.vue b/web/src/components/AgentPopover.vue index 0fb8e197..83ea1bca 100644 --- a/web/src/components/AgentPopover.vue +++ b/web/src/components/AgentPopover.vue @@ -39,17 +39,13 @@ :key="index" class="todo-item" > - - - - - - - - - - - +
+ + + + + +
{{ todo.content }} @@ -110,6 +106,13 @@ + + diff --git a/web/src/components/ToolCallingResult/ToolResultRenderer.vue b/web/src/components/ToolCallingResult/ToolResultRenderer.vue index 86a37940..0058622c 100644 --- a/web/src/components/ToolCallingResult/ToolResultRenderer.vue +++ b/web/src/components/ToolCallingResult/ToolResultRenderer.vue @@ -19,6 +19,12 @@ ref="graphResultRef" /> + + + { return props.resultContent }) +const todoListData = computed(() => { + if (props.toolName !== 'write_todos') return [] + + const raw = props.resultContent + + // 1. Try from parsedData (JSON object) + const data = parsedData.value + if (data && typeof data === 'object') { + if (Array.isArray(data)) return data + if (data.todos && Array.isArray(data.todos)) return data.todos + } + + // 2. Try parsing string if it matches specific pattern + if (typeof raw === 'string') { + let str = raw + if (str.startsWith('Updated todo list to ')) { + str = str.replace('Updated todo list to ', '') + } + + // Try regex parsing for Python-like string + const items = [] + // Matches {'content': '...', 'status': '...'} with escaped quotes support + // content might contain escaped quotes + const contentRegex = /'content':\s*'((?:[^'\\]|\\.)*)'/ + const statusRegex = /'status':\s*'((?:[^'\\]|\\.)*)'/ + + // Split by "}, {" roughly, or just look for objects + // Since it is a list of dicts, we can match individual dicts + const dictRegex = /\{.*?\}/g + const dictMatches = str.match(dictRegex) + + if (dictMatches) { + for (const dictStr of dictMatches) { + const contentMatch = dictStr.match(contentRegex) + const statusMatch = dictStr.match(statusRegex) + + if (contentMatch && statusMatch) { + items.push({ + content: contentMatch[1].replace(/\\'/g, "'").replace(/\\\\/g, "\\"), + status: statusMatch[1] + }) + } + } + } + if (items.length > 0) return items + } + + return [] +}) + +const isTodoListResult = computed(() => { + return props.toolName === 'write_todos' && todoListData.value.length > 0 +}) + // 判断是否为网页搜索结果 const isWebSearchResult = computed(() => { const toolNameLower = props.toolName.toLowerCase()