refactor: disable write_todos functionality across chat and UI components

- Commented out the write_todos tracking and messaging logic in the stream_new_chat.py file.
- Disabled the import and usage of WriteTodosToolUI in the new-chat page component.
- Updated related logic in the active connectors tab to remove indexing state handling for write_todos.
- These changes are part of a temporary disablement of the write_todos feature for further evaluation.
This commit is contained in:
Anish Sarkar 2026-01-02 18:22:38 +05:30
parent d576607d67
commit 2b01120c2b
4 changed files with 147 additions and 146 deletions

View file

@ -270,7 +270,8 @@ async def stream_new_chat(
# Track if we just finished a tool (text flows silently after tools) # Track if we just finished a tool (text flows silently after tools)
just_finished_tool: bool = False just_finished_tool: bool = False
# Track write_todos calls to show "Creating plan" vs "Updating plan" # Track write_todos calls to show "Creating plan" vs "Updating plan"
write_todos_call_count: int = 0 # Disabled for now
# write_todos_call_count: int = 0
def next_thinking_step_id() -> str: def next_thinking_step_id() -> str:
nonlocal thinking_step_counter nonlocal thinking_step_counter
@ -479,60 +480,60 @@ async def stream_new_chat(
status="in_progress", status="in_progress",
items=last_active_step_items, items=last_active_step_items,
) )
elif tool_name == "write_todos": # elif tool_name == "write_todos": # Disabled for now
# Track write_todos calls for better messaging # # Track write_todos calls for better messaging
write_todos_call_count += 1 # write_todos_call_count += 1
todos = ( # todos = (
tool_input.get("todos", []) # tool_input.get("todos", [])
if isinstance(tool_input, dict) # if isinstance(tool_input, dict)
else [] # else []
) # )
todo_count = len(todos) if isinstance(todos, list) else 0 # todo_count = len(todos) if isinstance(todos, list) else 0
if write_todos_call_count == 1: # if write_todos_call_count == 1:
# First call - creating the plan # # First call - creating the plan
last_active_step_title = "Creating plan" # last_active_step_title = "Creating plan"
last_active_step_items = [f"Defining {todo_count} tasks..."] # last_active_step_items = [f"Defining {todo_count} tasks..."]
else: # else:
# Subsequent calls - updating the plan # # Subsequent calls - updating the plan
# Try to provide context about what's being updated # # Try to provide context about what's being updated
in_progress_count = ( # in_progress_count = (
sum( # sum(
1 # 1
for t in todos # for t in todos
if isinstance(t, dict) # if isinstance(t, dict)
and t.get("status") == "in_progress" # and t.get("status") == "in_progress"
) # )
if isinstance(todos, list) # if isinstance(todos, list)
else 0 # else 0
) # )
completed_count = ( # completed_count = (
sum( # sum(
1 # 1
for t in todos # for t in todos
if isinstance(t, dict) # if isinstance(t, dict)
and t.get("status") == "completed" # and t.get("status") == "completed"
) # )
if isinstance(todos, list) # if isinstance(todos, list)
else 0 # else 0
) # )
last_active_step_title = "Updating progress" # last_active_step_title = "Updating progress"
last_active_step_items = ( # last_active_step_items = (
[ # [
f"Progress: {completed_count}/{todo_count} completed", # f"Progress: {completed_count}/{todo_count} completed",
f"In progress: {in_progress_count} tasks", # f"In progress: {in_progress_count} tasks",
] # ]
if completed_count > 0 # if completed_count > 0
else [f"Working on {todo_count} tasks"] # else [f"Working on {todo_count} tasks"]
) # )
yield streaming_service.format_thinking_step( # yield streaming_service.format_thinking_step(
step_id=tool_step_id, # step_id=tool_step_id,
title=last_active_step_title, # title=last_active_step_title,
status="in_progress", # status="in_progress",
items=last_active_step_items, # items=last_active_step_items,
) # )
elif tool_name == "generate_podcast": elif tool_name == "generate_podcast":
podcast_title = ( podcast_title = (
tool_input.get("podcast_title", "SurfSense Podcast") tool_input.get("podcast_title", "SurfSense Podcast")
@ -596,10 +597,12 @@ async def stream_new_chat(
raw_output = event.get("data", {}).get("output", "") raw_output = event.get("data", {}).get("output", "")
# Handle deepagents' write_todos Command object specially # Handle deepagents' write_todos Command object specially
if tool_name == "write_todos" and hasattr(raw_output, "update"): # Disabled for now
# deepagents returns a Command object - extract todos directly # if tool_name == "write_todos" and hasattr(raw_output, "update"):
tool_output = extract_todos_from_deepagents(raw_output) # # deepagents returns a Command object - extract todos directly
elif hasattr(raw_output, "content"): # tool_output = extract_todos_from_deepagents(raw_output)
# elif hasattr(raw_output, "content"):
if hasattr(raw_output, "content"):
# It's a ToolMessage object - extract the content # It's a ToolMessage object - extract the content
content = raw_output.content content = raw_output.content
# If content is a string that looks like JSON, try to parse it # If content is a string that looks like JSON, try to parse it
@ -758,63 +761,63 @@ async def stream_new_chat(
status="completed", status="completed",
items=completed_items, items=completed_items,
) )
elif tool_name == "write_todos": # elif tool_name == "write_todos": # Disabled for now
# Build completion items for planning/updating # # Build completion items for planning/updating
if isinstance(tool_output, dict): # if isinstance(tool_output, dict):
todos = tool_output.get("todos", []) # todos = tool_output.get("todos", [])
todo_count = len(todos) if isinstance(todos, list) else 0 # todo_count = len(todos) if isinstance(todos, list) else 0
completed_count = ( # completed_count = (
sum( # sum(
1 # 1
for t in todos # for t in todos
if isinstance(t, dict) # if isinstance(t, dict)
and t.get("status") == "completed" # and t.get("status") == "completed"
) # )
if isinstance(todos, list) # if isinstance(todos, list)
else 0 # else 0
) # )
in_progress_count = ( # in_progress_count = (
sum( # sum(
1 # 1
for t in todos # for t in todos
if isinstance(t, dict) # if isinstance(t, dict)
and t.get("status") == "in_progress" # and t.get("status") == "in_progress"
) # )
if isinstance(todos, list) # if isinstance(todos, list)
else 0 # else 0
) # )
# Use context-aware completion message # # Use context-aware completion message
if last_active_step_title == "Creating plan": # if last_active_step_title == "Creating plan":
completed_items = [f"Created {todo_count} tasks"] # completed_items = [f"Created {todo_count} tasks"]
else: # else:
# Updating progress - show stats # # Updating progress - show stats
completed_items = [ # completed_items = [
f"Progress: {completed_count}/{todo_count} completed", # f"Progress: {completed_count}/{todo_count} completed",
] # ]
if in_progress_count > 0: # if in_progress_count > 0:
# Find the currently in-progress task name # # Find the currently in-progress task name
in_progress_task = next( # in_progress_task = next(
( # (
t.get("content", "")[:40] # t.get("content", "")[:40]
for t in todos # for t in todos
if isinstance(t, dict) # if isinstance(t, dict)
and t.get("status") == "in_progress" # and t.get("status") == "in_progress"
), # ),
None, # None,
) # )
if in_progress_task: # if in_progress_task:
completed_items.append( # completed_items.append(
f"Current: {in_progress_task}..." # f"Current: {in_progress_task}..."
) # )
else: # else:
completed_items = ["Plan updated"] # completed_items = ["Plan updated"]
yield streaming_service.format_thinking_step( # yield streaming_service.format_thinking_step(
step_id=original_step_id, # step_id=original_step_id,
title=last_active_step_title, # title=last_active_step_title,
status="completed", # status="completed",
items=completed_items, # items=completed_items,
) # )
elif tool_name == "ls": elif tool_name == "ls":
# Build completion items showing file names found # Build completion items showing file names found
if isinstance(tool_output, dict): if isinstance(tool_output, dict):
@ -992,27 +995,27 @@ async def stream_new_chat(
yield streaming_service.format_terminal_info( yield streaming_service.format_terminal_info(
"Knowledge base search completed", "success" "Knowledge base search completed", "success"
) )
elif tool_name == "write_todos": # elif tool_name == "write_todos": # Disabled for now
# Stream the full write_todos result so frontend can render the Plan component # # Stream the full write_todos result so frontend can render the Plan component
yield streaming_service.format_tool_output_available( # yield streaming_service.format_tool_output_available(
tool_call_id, # tool_call_id,
tool_output # tool_output
if isinstance(tool_output, dict) # if isinstance(tool_output, dict)
else {"result": tool_output}, # else {"result": tool_output},
) # )
# Send terminal message with plan info # # Send terminal message with plan info
if isinstance(tool_output, dict): # if isinstance(tool_output, dict):
todos = tool_output.get("todos", []) # todos = tool_output.get("todos", [])
todo_count = len(todos) if isinstance(todos, list) else 0 # todo_count = len(todos) if isinstance(todos, list) else 0
yield streaming_service.format_terminal_info( # yield streaming_service.format_terminal_info(
f"Plan created ({todo_count} tasks)", # f"Plan created ({todo_count} tasks)",
"success", # "success",
) # )
else: # else:
yield streaming_service.format_terminal_info( # yield streaming_service.format_terminal_info(
"Plan created", # "Plan created",
"success", # "success",
) # )
else: else:
# Default handling for other tools # Default handling for other tools
yield streaming_service.format_tool_output_available( yield streaming_service.format_tool_output_available(

View file

@ -20,7 +20,7 @@ import {
} from "@/atoms/chat/mentioned-documents.atom"; } from "@/atoms/chat/mentioned-documents.atom";
import { import {
clearPlanOwnerRegistry, clearPlanOwnerRegistry,
extractWriteTodosFromContent, // extractWriteTodosFromContent,
hydratePlanStateAtom, hydratePlanStateAtom,
} from "@/atoms/chat/plan-state.atom"; } from "@/atoms/chat/plan-state.atom";
import { Thread } from "@/components/assistant-ui/thread"; import { Thread } from "@/components/assistant-ui/thread";
@ -30,7 +30,7 @@ import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast"; import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview"; import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview";
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage"; import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
import { WriteTodosToolUI } from "@/components/tool-ui/write-todos"; // import { WriteTodosToolUI } from "@/components/tool-ui/write-todos";
import { getBearerToken } from "@/lib/auth-utils"; import { getBearerToken } from "@/lib/auth-utils";
import { createAttachmentAdapter, extractAttachmentContent } from "@/lib/chat/attachment-adapter"; import { createAttachmentAdapter, extractAttachmentContent } from "@/lib/chat/attachment-adapter";
import { import {
@ -199,7 +199,7 @@ const TOOLS_WITH_UI = new Set([
"link_preview", "link_preview",
"display_image", "display_image",
"scrape_webpage", "scrape_webpage",
"write_todos", // "write_todos", // Disabled for now
]); ]);
/** /**
@ -291,10 +291,11 @@ export default function NewChatPage() {
restoredThinkingSteps.set(`msg-${msg.id}`, steps); restoredThinkingSteps.set(`msg-${msg.id}`, steps);
} }
// Hydrate write_todos plan state from persisted tool calls // Hydrate write_todos plan state from persisted tool calls
const writeTodosCalls = extractWriteTodosFromContent(msg.content); // Disabled for now
for (const todoData of writeTodosCalls) { // const writeTodosCalls = extractWriteTodosFromContent(msg.content);
hydratePlanState(todoData); // for (const todoData of writeTodosCalls) {
} // hydratePlanState(todoData);
// }
} }
if (msg.role === "user") { if (msg.role === "user") {
const docs = extractMentionedDocuments(msg.content); const docs = extractMentionedDocuments(msg.content);
@ -911,7 +912,7 @@ export default function NewChatPage() {
<LinkPreviewToolUI /> <LinkPreviewToolUI />
<DisplayImageToolUI /> <DisplayImageToolUI />
<ScrapeWebpageToolUI /> <ScrapeWebpageToolUI />
<WriteTodosToolUI /> {/* <WriteTodosToolUI /> Disabled for now */}
<div className="flex flex-col h-[calc(100vh-64px)] overflow-hidden"> <div className="flex flex-col h-[calc(100vh-64px)] overflow-hidden">
<Thread <Thread
messageThinkingSteps={messageThinkingSteps} messageThinkingSteps={messageThinkingSteps}

View file

@ -175,12 +175,10 @@ export const ConnectorCard: FC<ConnectorCardProps> = ({
!isConnected && "shadow-xs" !isConnected && "shadow-xs"
)} )}
onClick={isConnected ? onManage : onConnect} onClick={isConnected ? onManage : onConnect}
disabled={isConnecting || isIndexing} disabled={isConnecting}
> >
{isConnecting ? ( {isConnecting ? (
<Loader2 className="size-3 animate-spin" /> <Loader2 className="size-3 animate-spin" />
) : isIndexing ? (
"Syncing..."
) : isConnected ? ( ) : isConnected ? (
"Manage" "Manage"
) : id === "youtube-crawler" ? ( ) : id === "youtube-crawler" ? (

View file

@ -205,9 +205,8 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
size="sm" size="sm"
className="h-8 text-[11px] px-3 rounded-lg font-medium bg-white text-slate-700 hover:bg-slate-50 border-0 shadow-xs dark:bg-secondary dark:text-secondary-foreground dark:hover:bg-secondary/80" className="h-8 text-[11px] px-3 rounded-lg font-medium bg-white text-slate-700 hover:bg-slate-50 border-0 shadow-xs dark:bg-secondary dark:text-secondary-foreground dark:hover:bg-secondary/80"
onClick={onManage ? () => onManage(connector) : undefined} onClick={onManage ? () => onManage(connector) : undefined}
disabled={isIndexing}
> >
{isIndexing ? "Syncing..." : "Manage"} Manage
</Button> </Button>
</div> </div>
); );