feat&fix: add brief task status retrieval and improve task status update mechanism
This commit is contained in:
145
monitor/main.py
145
monitor/main.py
@@ -151,6 +151,118 @@ def get_task_status(task_type, task_id):
|
||||
"result": result_content
|
||||
}
|
||||
|
||||
def get_task_status_brief(task_type, task_id):
|
||||
"""
|
||||
Get brief status info for a task, without detailed step data, for fast homepage loading.
|
||||
"""
|
||||
result_dir = os.path.join(RESULTS_BASE_PATH, task_type, task_id)
|
||||
|
||||
if not os.path.exists(result_dir):
|
||||
return {
|
||||
"status": "Not Started",
|
||||
"progress": 0,
|
||||
"max_steps": MAX_STEPS,
|
||||
"last_update": None
|
||||
}
|
||||
|
||||
traj_file = os.path.join(result_dir, "traj.jsonl")
|
||||
log_file = os.path.join(result_dir, "runtime.log")
|
||||
result_file = os.path.join(result_dir, "result.txt")
|
||||
|
||||
if not os.path.exists(traj_file):
|
||||
return {
|
||||
"status": "Preparing",
|
||||
"progress": 0,
|
||||
"max_steps": MAX_STEPS,
|
||||
"last_update": datetime.fromtimestamp(os.path.getmtime(result_dir)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
}
|
||||
|
||||
# Get file line count and last line without reading the whole file
|
||||
import subprocess
|
||||
|
||||
# Use wc -l to get line count
|
||||
try:
|
||||
result = subprocess.run(['wc', '-l', traj_file], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
step_count = int(result.stdout.strip().split()[0])
|
||||
else:
|
||||
step_count = 0
|
||||
except:
|
||||
step_count = 0
|
||||
|
||||
# Use tail -n 1 to get last line
|
||||
last_step_data = None
|
||||
if step_count > 0:
|
||||
try:
|
||||
result = subprocess.run(['tail', '-n', '1', traj_file], capture_output=True, text=True)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
last_step_data = json.loads(result.stdout.strip())
|
||||
except:
|
||||
pass
|
||||
|
||||
if step_count == 0:
|
||||
return {
|
||||
"status": "Initializing",
|
||||
"progress": 0,
|
||||
"max_steps": MAX_STEPS,
|
||||
"last_update": datetime.fromtimestamp(os.path.getmtime(traj_file)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
}
|
||||
|
||||
# Set default status to "Running"
|
||||
status = "Running"
|
||||
|
||||
# Determine status from last step data
|
||||
if last_step_data:
|
||||
if last_step_data.get("done", False):
|
||||
status = "Done"
|
||||
elif last_step_data.get("Error", False):
|
||||
status = "Error"
|
||||
|
||||
# If step count reaches max, consider as done
|
||||
if step_count >= MAX_STEPS:
|
||||
status = "Done (Max Steps)"
|
||||
|
||||
# Quickly check exit condition in log file (only last few lines)
|
||||
if os.path.exists(log_file) and status == "Running":
|
||||
try:
|
||||
# Use tail to read last 2 lines of log file
|
||||
result = subprocess.run(['tail', '-n', '2', log_file], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
log_tail = result.stdout
|
||||
if "message_exit: True" in log_tail:
|
||||
status = "Done (Message Exit)"
|
||||
except:
|
||||
pass
|
||||
|
||||
# If step count reaches max again (double check)
|
||||
if step_count >= MAX_STEPS:
|
||||
status = "Done (Max Steps)"
|
||||
|
||||
# Get last update time
|
||||
last_update = "None"
|
||||
if last_step_data and "action_timestamp" in last_step_data:
|
||||
try:
|
||||
last_update = datetime.strptime(last_step_data["action_timestamp"], "%Y%m%d@%H%M%S").strftime("%Y-%m-%d %H:%M:%S")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Get result content if finished
|
||||
result_content = None
|
||||
if status.startswith("Done") and os.path.exists(result_file):
|
||||
try:
|
||||
with open(result_file, 'r') as f:
|
||||
result_content = f.read().strip()
|
||||
except:
|
||||
result_content = "Result file not found"
|
||||
|
||||
return {
|
||||
"status": status,
|
||||
"progress": step_count,
|
||||
"max_steps": MAX_STEPS,
|
||||
"last_update": last_update,
|
||||
"result": result_content
|
||||
}
|
||||
|
||||
def get_all_tasks_status():
|
||||
task_list = load_task_list()
|
||||
result = {}
|
||||
@@ -176,6 +288,34 @@ def get_all_tasks_status():
|
||||
|
||||
return result
|
||||
|
||||
def get_all_tasks_status_brief():
|
||||
"""
|
||||
Get brief status info for all tasks, without detailed step data, for fast homepage loading.
|
||||
"""
|
||||
task_list = load_task_list()
|
||||
result = {}
|
||||
|
||||
for task_type, task_ids in task_list.items():
|
||||
result[task_type] = []
|
||||
for task_id in task_ids:
|
||||
task_info = get_task_info(task_type, task_id)
|
||||
task_status = get_task_status_brief(task_type, task_id)
|
||||
|
||||
if task_info:
|
||||
result[task_type].append({
|
||||
"id": task_id,
|
||||
"instruction": task_info.get("instruction", "No instruction provided"),
|
||||
"status": task_status
|
||||
})
|
||||
else:
|
||||
result[task_type].append({
|
||||
"id": task_id,
|
||||
"instruction": "No task info available",
|
||||
"status": task_status
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template("index.html")
|
||||
@@ -199,6 +339,11 @@ def api_tasks():
|
||||
"""Task status API"""
|
||||
return jsonify(get_all_tasks_status())
|
||||
|
||||
@app.route('/api/tasks/brief')
|
||||
def api_tasks_brief():
|
||||
"""Return brief status info for all tasks, without detailed step data, for fast homepage loading."""
|
||||
return jsonify(get_all_tasks_status_brief())
|
||||
|
||||
@app.route('/task/<task_type>/<task_id>/screenshot/<path:filename>')
|
||||
def task_screenshot(task_type, task_id, filename):
|
||||
"""Get task screenshot"""
|
||||
|
||||
Reference in New Issue
Block a user