mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-04 23:39:33 +08:00
fix: replace undefined mapToStruct with parseActionOptions in MCP server
- Replace all mapToStruct calls with parseActionOptions function - Add parseActionOptions implementation for MCP request parameter parsing - Remove undefined mapToStruct function that was causing compilation errors - Standardize parameter names (fromX/fromY/toX/toY -> from_x/from_y/to_x/to_y) - Add AntiRisk support for TapAbsXY and Drag tools - Improve parameter validation for Drag tool - Update corresponding test cases to match new parameter names This fixes compilation errors and ensures all MCP tools work correctly.
This commit is contained in:
@@ -1 +1 @@
|
|||||||
v5.0.0-beta-2505291922
|
v5.0.0-beta-2505292037
|
||||||
|
|||||||
@@ -311,9 +311,9 @@ func (t *ToolTapXY) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get options directly since ActionOptions is now ActionOptions
|
// Get options directly since ActionOptions is now ActionOptions
|
||||||
@@ -382,9 +382,9 @@ func (t *ToolTapAbsXY) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get options directly since ActionOptions is now ActionOptions
|
// Get options directly since ActionOptions is now ActionOptions
|
||||||
@@ -393,6 +393,11 @@ func (t *ToolTapAbsXY) Implement() server.ToolHandlerFunc {
|
|||||||
// Add default options
|
// Add default options
|
||||||
opts = append(opts, option.WithPreMarkOperation(true))
|
opts = append(opts, option.WithPreMarkOperation(true))
|
||||||
|
|
||||||
|
// Add AntiRisk support
|
||||||
|
if unifiedReq.AntiRisk {
|
||||||
|
opts = append(opts, option.WithAntiRisk(true))
|
||||||
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
if unifiedReq.X == 0 || unifiedReq.Y == 0 {
|
if unifiedReq.X == 0 || unifiedReq.Y == 0 {
|
||||||
return nil, fmt.Errorf("x and y coordinates are required")
|
return nil, fmt.Errorf("x and y coordinates are required")
|
||||||
@@ -453,9 +458,9 @@ func (t *ToolTapByOCR) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get options directly since ActionOptions is now ActionOptions
|
// Get options directly since ActionOptions is now ActionOptions
|
||||||
@@ -517,9 +522,9 @@ func (t *ToolTapByCV) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get options directly since ActionOptions is now ActionOptions
|
// Get options directly since ActionOptions is now ActionOptions
|
||||||
@@ -578,9 +583,9 @@ func (t *ToolDoubleTapXY) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
@@ -669,9 +674,9 @@ func (t *ToolLaunchApp) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if unifiedReq.PackageName == "" {
|
if unifiedReq.PackageName == "" {
|
||||||
@@ -722,9 +727,9 @@ func (t *ToolTerminateApp) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if unifiedReq.PackageName == "" {
|
if unifiedReq.PackageName == "" {
|
||||||
@@ -852,9 +857,9 @@ func (t *ToolPressButton) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Press button action logic
|
// Press button action logic
|
||||||
@@ -964,9 +969,9 @@ func (t *ToolSwipeDirection) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
swipeDirection := unifiedReq.Direction.(string)
|
swipeDirection := unifiedReq.Direction.(string)
|
||||||
|
|
||||||
@@ -1057,9 +1062,9 @@ func (t *ToolSwipeCoordinate) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
@@ -1101,10 +1106,10 @@ func (t *ToolSwipeCoordinate) Implement() server.ToolHandlerFunc {
|
|||||||
func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
|
func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
|
||||||
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
|
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
|
||||||
arguments := map[string]any{
|
arguments := map[string]any{
|
||||||
"fromX": paramSlice[0],
|
"from_x": paramSlice[0],
|
||||||
"fromY": paramSlice[1],
|
"from_y": paramSlice[1],
|
||||||
"toX": paramSlice[2],
|
"to_x": paramSlice[2],
|
||||||
"toY": paramSlice[3],
|
"to_y": paramSlice[3],
|
||||||
}
|
}
|
||||||
// Add duration and press duration from options
|
// Add duration and press duration from options
|
||||||
if duration := action.ActionOptions.Duration; duration > 0 {
|
if duration := action.ActionOptions.Duration; duration > 0 {
|
||||||
@@ -1145,9 +1150,9 @@ func (t *ToolSwipeToTapApp) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build action options from request structure
|
// Build action options from request structure
|
||||||
@@ -1214,9 +1219,9 @@ func (t *ToolSwipeToTapText) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build action options from request structure
|
// Build action options from request structure
|
||||||
@@ -1286,9 +1291,9 @@ func (t *ToolSwipeToTapTexts) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build action options from request structure
|
// Build action options from request structure
|
||||||
@@ -1363,20 +1368,27 @@ func (t *ToolDrag) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters - check if coordinates are provided (not just non-zero)
|
||||||
if unifiedReq.FromX == 0 || unifiedReq.FromY == 0 || unifiedReq.ToX == 0 || unifiedReq.ToY == 0 {
|
_, hasFromX := request.Params.Arguments["from_x"]
|
||||||
return nil, fmt.Errorf("fromX, fromY, toX, and toY coordinates are required")
|
_, hasFromY := request.Params.Arguments["from_y"]
|
||||||
|
_, hasToX := request.Params.Arguments["to_x"]
|
||||||
|
_, hasToY := request.Params.Arguments["to_y"]
|
||||||
|
if !hasFromX || !hasFromY || !hasToX || !hasToY {
|
||||||
|
return nil, fmt.Errorf("from_x, from_y, to_x, and to_y coordinates are required")
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := []option.ActionOption{}
|
opts := []option.ActionOption{}
|
||||||
if unifiedReq.Duration > 0 {
|
if unifiedReq.Duration > 0 {
|
||||||
opts = append(opts, option.WithDuration(unifiedReq.Duration/1000.0))
|
opts = append(opts, option.WithDuration(unifiedReq.Duration/1000.0))
|
||||||
}
|
}
|
||||||
|
if unifiedReq.AntiRisk {
|
||||||
|
opts = append(opts, option.WithAntiRisk(true))
|
||||||
|
}
|
||||||
|
|
||||||
// Drag action logic
|
// Drag action logic
|
||||||
log.Info().
|
log.Info().
|
||||||
@@ -1397,27 +1409,22 @@ func (t *ToolDrag) Implement() server.ToolHandlerFunc {
|
|||||||
func (t *ToolDrag) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
|
func (t *ToolDrag) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
|
||||||
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
|
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
|
||||||
arguments := map[string]any{
|
arguments := map[string]any{
|
||||||
"fromX": paramSlice[0],
|
"from_x": paramSlice[0],
|
||||||
"fromY": paramSlice[1],
|
"from_y": paramSlice[1],
|
||||||
"toX": paramSlice[2],
|
"to_x": paramSlice[2],
|
||||||
"toY": paramSlice[3],
|
"to_y": paramSlice[3],
|
||||||
}
|
}
|
||||||
// Add duration from options
|
// Add duration from options
|
||||||
if duration := action.ActionOptions.Duration; duration > 0 {
|
if duration := action.ActionOptions.Duration; duration > 0 {
|
||||||
arguments["duration"] = duration * 1000 // convert to milliseconds
|
arguments["duration"] = duration * 1000 // convert to milliseconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract all action options
|
||||||
|
extractActionOptionsToArguments(action.GetOptions(), arguments)
|
||||||
|
|
||||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||||
}
|
}
|
||||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid drag params: %v", action.Params)
|
return mcp.CallToolRequest{}, fmt.Errorf("invalid drag parameters: %v", action.Params)
|
||||||
}
|
|
||||||
|
|
||||||
// mapToStruct convert map[string]any to target struct
|
|
||||||
func mapToStruct(m map[string]any, out interface{}) error {
|
|
||||||
b, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return json.Unmarshal(b, out)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractActionOptionsToArguments extracts action options and adds them to arguments map
|
// extractActionOptionsToArguments extracts action options and adds them to arguments map
|
||||||
@@ -1448,15 +1455,18 @@ func extractActionOptionsToArguments(actionOptions []option.ActionOption, argume
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add numeric options only if they have meaningful values
|
// Add numeric options only if they have meaningful values and don't already exist
|
||||||
if tempOptions.MaxRetryTimes > 0 {
|
if tempOptions.MaxRetryTimes > 0 {
|
||||||
arguments["max_retry_times"] = tempOptions.MaxRetryTimes
|
arguments["max_retry_times"] = tempOptions.MaxRetryTimes
|
||||||
}
|
}
|
||||||
if tempOptions.Index != 0 {
|
if tempOptions.Index != 0 {
|
||||||
arguments["index"] = tempOptions.Index
|
arguments["index"] = tempOptions.Index
|
||||||
}
|
}
|
||||||
|
// Only set duration if it's not already set (to avoid overriding tool-specific conversions)
|
||||||
if tempOptions.Duration > 0 {
|
if tempOptions.Duration > 0 {
|
||||||
arguments["duration"] = tempOptions.Duration
|
if _, exists := arguments["duration"]; !exists {
|
||||||
|
arguments["duration"] = tempOptions.Duration
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if tempOptions.PressDuration > 0 {
|
if tempOptions.PressDuration > 0 {
|
||||||
arguments["press_duration"] = tempOptions.PressDuration
|
arguments["press_duration"] = tempOptions.PressDuration
|
||||||
@@ -1562,9 +1572,9 @@ func (t *ToolInput) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if unifiedReq.Text == "" {
|
if unifiedReq.Text == "" {
|
||||||
@@ -1613,9 +1623,9 @@ func (t *ToolWebLoginNoneUI) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web login none UI action logic
|
// Web login none UI action logic
|
||||||
@@ -1661,9 +1671,9 @@ func (t *ToolAppInstall) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// App install action logic
|
// App install action logic
|
||||||
@@ -1710,9 +1720,9 @@ func (t *ToolAppUninstall) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// App uninstall action logic
|
// App uninstall action logic
|
||||||
@@ -1759,9 +1769,9 @@ func (t *ToolAppClear) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// App clear action logic
|
// App clear action logic
|
||||||
@@ -1808,9 +1818,9 @@ func (t *ToolSecondaryClick) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
@@ -1863,9 +1873,9 @@ func (t *ToolHoverBySelector) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hover by selector action logic
|
// Hover by selector action logic
|
||||||
@@ -1912,9 +1922,9 @@ func (t *ToolTapBySelector) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tap by selector action logic
|
// Tap by selector action logic
|
||||||
@@ -1961,9 +1971,9 @@ func (t *ToolSecondaryClickBySelector) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secondary click by selector action logic
|
// Secondary click by selector action logic
|
||||||
@@ -2010,9 +2020,9 @@ func (t *ToolWebCloseTab) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
@@ -2077,9 +2087,9 @@ func (t *ToolSetIme) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set IME action logic
|
// Set IME action logic
|
||||||
@@ -2126,9 +2136,9 @@ func (t *ToolGetSource) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get source action logic
|
// Get source action logic
|
||||||
@@ -2228,9 +2238,9 @@ func (t *ToolSleepMS) Options() []mcp.ToolOption {
|
|||||||
|
|
||||||
func (t *ToolSleepMS) Implement() server.ToolHandlerFunc {
|
func (t *ToolSleepMS) Implement() server.ToolHandlerFunc {
|
||||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required parameters
|
// Validate required parameters
|
||||||
@@ -2279,9 +2289,9 @@ func (t *ToolSleepRandom) Options() []mcp.ToolOption {
|
|||||||
|
|
||||||
func (t *ToolSleepRandom) Implement() server.ToolHandlerFunc {
|
func (t *ToolSleepRandom) Implement() server.ToolHandlerFunc {
|
||||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep random action logic
|
// Sleep random action logic
|
||||||
@@ -2363,9 +2373,9 @@ func (t *ToolAIAction) Implement() server.ToolHandlerFunc {
|
|||||||
return nil, fmt.Errorf("setup driver failed: %w", err)
|
return nil, fmt.Errorf("setup driver failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI action logic
|
// AI action logic
|
||||||
@@ -2407,9 +2417,9 @@ func (t *ToolFinished) Options() []mcp.ToolOption {
|
|||||||
|
|
||||||
func (t *ToolFinished) Implement() server.ToolHandlerFunc {
|
func (t *ToolFinished) Implement() server.ToolHandlerFunc {
|
||||||
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
var unifiedReq option.ActionOptions
|
unifiedReq, err := parseActionOptions(request.Params.Arguments)
|
||||||
if err := mapToStruct(request.Params.Arguments, &unifiedReq); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse parameters error: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Info().Str("reason", unifiedReq.Content).Msg("task finished")
|
log.Info().Str("reason", unifiedReq.Content).Msg("task finished")
|
||||||
|
|
||||||
@@ -2433,3 +2443,18 @@ func getFloat64ValueOrDefault(value float64, defaultValue float64) float64 {
|
|||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseActionOptions converts MCP request arguments to ActionOptions struct
|
||||||
|
func parseActionOptions(arguments map[string]any) (*option.ActionOptions, error) {
|
||||||
|
b, err := json.Marshal(arguments)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("marshal arguments failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var actionOptions option.ActionOptions
|
||||||
|
if err := json.Unmarshal(b, &actionOptions); err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshal to ActionOptions failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &actionOptions, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ func TestToolSwipe(t *testing.T) {
|
|||||||
assert.Equal(t, 1.5, request.Params.Arguments["duration"])
|
assert.Equal(t, 1.5, request.Params.Arguments["duration"])
|
||||||
assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"])
|
assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"])
|
||||||
|
|
||||||
// Test ConvertActionToCallToolRequest with coordinate params ([]float64)
|
// Test ConvertActionToCallToolRequest with coordinate params
|
||||||
coordinateAction := MobileAction{
|
coordinateAction := MobileAction{
|
||||||
Method: option.ACTION_Swipe,
|
Method: option.ACTION_Swipe,
|
||||||
Params: []float64{0.1, 0.2, 0.8, 0.9},
|
Params: []float64{0.1, 0.2, 0.8, 0.9},
|
||||||
@@ -467,10 +467,10 @@ func TestToolSwipe(t *testing.T) {
|
|||||||
request, err = tool.ConvertActionToCallToolRequest(coordinateAction)
|
request, err = tool.ConvertActionToCallToolRequest(coordinateAction)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, string(option.ACTION_Swipe), request.Params.Name)
|
assert.Equal(t, string(option.ACTION_Swipe), request.Params.Name)
|
||||||
assert.Equal(t, 0.1, request.Params.Arguments["fromX"])
|
assert.Equal(t, 0.1, request.Params.Arguments["from_x"])
|
||||||
assert.Equal(t, 0.2, request.Params.Arguments["fromY"])
|
assert.Equal(t, 0.2, request.Params.Arguments["from_y"])
|
||||||
assert.Equal(t, 0.8, request.Params.Arguments["toX"])
|
assert.Equal(t, 0.8, request.Params.Arguments["to_x"])
|
||||||
assert.Equal(t, 0.9, request.Params.Arguments["toY"])
|
assert.Equal(t, 0.9, request.Params.Arguments["to_y"])
|
||||||
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
|
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
|
||||||
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
|
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
|
||||||
|
|
||||||
@@ -556,10 +556,10 @@ func TestToolSwipeCoordinate(t *testing.T) {
|
|||||||
request, err := tool.ConvertActionToCallToolRequest(action)
|
request, err := tool.ConvertActionToCallToolRequest(action)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, string(option.ACTION_SwipeCoordinate), request.Params.Name)
|
assert.Equal(t, string(option.ACTION_SwipeCoordinate), request.Params.Name)
|
||||||
assert.Equal(t, 0.1, request.Params.Arguments["fromX"])
|
assert.Equal(t, 0.1, request.Params.Arguments["from_x"])
|
||||||
assert.Equal(t, 0.2, request.Params.Arguments["fromY"])
|
assert.Equal(t, 0.2, request.Params.Arguments["from_y"])
|
||||||
assert.Equal(t, 0.8, request.Params.Arguments["toX"])
|
assert.Equal(t, 0.8, request.Params.Arguments["to_x"])
|
||||||
assert.Equal(t, 0.9, request.Params.Arguments["toY"])
|
assert.Equal(t, 0.9, request.Params.Arguments["to_y"])
|
||||||
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
|
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
|
||||||
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
|
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
|
||||||
|
|
||||||
@@ -724,10 +724,10 @@ func TestToolDrag(t *testing.T) {
|
|||||||
request, err := tool.ConvertActionToCallToolRequest(action)
|
request, err := tool.ConvertActionToCallToolRequest(action)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, string(option.ACTION_Drag), request.Params.Name)
|
assert.Equal(t, string(option.ACTION_Drag), request.Params.Name)
|
||||||
assert.Equal(t, 0.1, request.Params.Arguments["fromX"])
|
assert.Equal(t, 0.1, request.Params.Arguments["from_x"])
|
||||||
assert.Equal(t, 0.2, request.Params.Arguments["fromY"])
|
assert.Equal(t, 0.2, request.Params.Arguments["from_y"])
|
||||||
assert.Equal(t, 0.8, request.Params.Arguments["toX"])
|
assert.Equal(t, 0.8, request.Params.Arguments["to_x"])
|
||||||
assert.Equal(t, 0.9, request.Params.Arguments["toY"])
|
assert.Equal(t, 0.9, request.Params.Arguments["to_y"])
|
||||||
assert.Equal(t, 2500.0, request.Params.Arguments["duration"]) // converted to milliseconds
|
assert.Equal(t, 2500.0, request.Params.Arguments["duration"]) // converted to milliseconds
|
||||||
|
|
||||||
// Test ConvertActionToCallToolRequest with invalid params
|
// Test ConvertActionToCallToolRequest with invalid params
|
||||||
|
|||||||
Reference in New Issue
Block a user