Skip to content

Commit ee0ffc6

Browse files
committed
Added action_feedback through ctx.report_progress. Tested and working in Cursor, not showing in ChatGPT.
1 parent bf2dd8b commit ee0ffc6

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

server.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import argparse
2+
import asyncio
23
import io
34
import json
45
import os
56
import time
67
import uuid
78
from typing import Any, Dict, List, Optional, Union
89

9-
from fastmcp import FastMCP
10+
from fastmcp import Context, FastMCP
1011
from fastmcp.utilities.types import Image
1112
from PIL import Image as PILImage
1213

@@ -2463,7 +2464,7 @@ def inspect_all_actions() -> dict:
24632464
"send_action_goal('/turtle1/rotate_absolute', 'turtlesim/action/RotateAbsolute', {'theta': 1.57})"
24642465
)
24652466
)
2466-
def send_action_goal(action_name: str, action_type: str, goal: dict, timeout: float = None) -> dict:
2467+
async def send_action_goal(action_name: str, action_type: str, goal: dict, timeout: float = None, ctx: Context = None) -> dict:
24672468
"""
24682469
Send a goal to a ROS action server. Works only with ROS 2.
24692470
@@ -2515,16 +2516,27 @@ def send_action_goal(action_name: str, action_type: str, goal: dict, timeout: fl
25152516
actual_timeout = timeout if timeout is not None else 10.0 # Default 10 seconds
25162517
start_time = time.time()
25172518
last_feedback = None # Store the last feedback message
2519+
feedback_count = 0 # Count feedback messages received
25182520

25192521
while time.time() - start_time < actual_timeout:
2520-
response = ws_manager.receive(timeout=actual_timeout - (time.time() - start_time))
2522+
elapsed_time = time.time() - start_time
2523+
2524+
response = ws_manager.receive(timeout=actual_timeout - elapsed_time)
25212525

25222526
if response:
25232527
try:
25242528
msg_data = json.loads(response)
25252529

25262530
# Handle action_result messages (final completion)
25272531
if msg_data.get("op") == "action_result":
2532+
# Report completion
2533+
if ctx:
2534+
try:
2535+
completion_msg = f"Action completed successfully (received {feedback_count} feedback messages)"
2536+
await ctx.report_progress(progress=feedback_count, total=None, message=completion_msg)
2537+
except Exception:
2538+
pass
2539+
25282540
return {
25292541
"action": action_name,
25302542
"action_type": action_type,
@@ -2534,16 +2546,35 @@ def send_action_goal(action_name: str, action_type: str, goal: dict, timeout: fl
25342546
"result": msg_data.get("values", {}),
25352547
}
25362548

2537-
# Store action_feedback messages for timeout case
2549+
# Store action_feedback messages and report progress
25382550
if msg_data.get("op") == "action_feedback":
2551+
feedback_count += 1
25392552
last_feedback = msg_data
2553+
2554+
# Report feedback progress
2555+
if ctx:
2556+
try:
2557+
feedback_values = msg_data.get("values", {})
2558+
feedback_msg = f"Action feedback #{feedback_count}: {str(feedback_values)[:100]}..."
2559+
await ctx.report_progress(progress=feedback_count, total=None, message=feedback_msg)
2560+
except Exception:
2561+
pass
25402562

25412563
except json.JSONDecodeError:
25422564
continue
2565+
else:
2566+
# No response received, continue waiting
2567+
pass
25432568

2544-
time.sleep(0.1)
2569+
await asyncio.sleep(0.1)
25452570

25462571
# Timeout - return last feedback if available
2572+
if ctx and feedback_count > 0:
2573+
try:
2574+
await ctx.report_progress(progress=feedback_count, total=None, message=f"Action timed out after {actual_timeout} seconds (received {feedback_count} feedback messages)")
2575+
except Exception:
2576+
pass
2577+
25472578
result = {
25482579
"action": action_name,
25492580
"action_type": action_type,

0 commit comments

Comments
 (0)