Move TASKS.md to session-specific directory in ~/.openhands (#10493)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Ryan H. Tran 2025-08-20 21:26:55 +07:00 committed by GitHub
parent c763f0e368
commit e03a1f4e37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -67,6 +67,7 @@ from openhands.runtime.plugins import (
from openhands.runtime.runtime_status import RuntimeStatus
from openhands.runtime.utils.edit import FileEditRuntimeMixin
from openhands.runtime.utils.git_handler import CommandResult, GitHandler
from openhands.storage.locations import get_conversation_dir
from openhands.utils.async_utils import (
GENERAL_TIMEOUT,
call_async_from_sync,
@ -876,8 +877,14 @@ fi
if isinstance(action, AgentThinkAction):
return AgentThinkObservation('Your thought has been logged.')
elif isinstance(action, TaskTrackingAction):
# If `command` is `plan`, write the serialized task list to the file TASKS.md under `.openhands/`
# Get the session-specific task file path
conversation_dir = get_conversation_dir(
self.sid, self.event_stream.user_id
)
task_file_path = f'{conversation_dir}TASKS.md'
if action.command == 'plan':
# Write the serialized task list to the session directory
content = '# Task List\n\n'
for i, task in enumerate(action.task_list, 1):
status_icon = {
@ -886,33 +893,39 @@ fi
'done': '',
}.get(task.get('status', 'todo'), '')
content += f'{i}. {status_icon} {task.get("title", "")}\n{task.get("notes", "")}\n'
write_obs = self.write(
FileWriteAction(path='.openhands/TASKS.md', content=content)
)
if isinstance(write_obs, ErrorObservation):
try:
self.event_stream.file_store.write(task_file_path, content)
return TaskTrackingObservation(
content=f'Task list has been updated with {len(action.task_list)} items. Stored in session directory: {task_file_path}',
command=action.command,
task_list=action.task_list,
)
except Exception as e:
return ErrorObservation(
f'Failed to write task list to .openhands/TASKS.md: {write_obs.content}'
f'Failed to write task list to session directory {task_file_path}: {str(e)}'
)
return TaskTrackingObservation(
content=f'Task list has been updated with {len(action.task_list)} items.',
command=action.command,
task_list=action.task_list,
)
elif action.command == 'view':
# If `command` is `view`, read the TASKS.md file and return its content
read_obs = self.read(FileReadAction(path='.openhands/TASKS.md'))
if isinstance(read_obs, FileReadObservation):
# Read the TASKS.md file from the session directory
try:
content = self.event_stream.file_store.read(task_file_path)
return TaskTrackingObservation(
content=read_obs.content,
content=content,
command=action.command,
task_list=[], # Empty for view command
)
else:
return TaskTrackingObservation( # Return observation if error occurs because file might not exist yet
except FileNotFoundError:
return TaskTrackingObservation(
command=action.command,
task_list=[],
content=f'Failed to read the task list. Error: {read_obs.content}',
content='No task list found. Use the "plan" command to create one.',
)
except Exception as e:
return TaskTrackingObservation(
command=action.command,
task_list=[],
content=f'Failed to read the task list from session directory {task_file_path}. Error: {str(e)}',
)
return NullObservation('')