refactor: move MobileAction to option package and update imports

- Move MobileAction struct from uixt package to uixt/option package
- Delete uixt/driver_action.go file as MobileAction is now in option package
- Update all import statements across the codebase to use option.MobileAction
- Update ActionTool interface to use option.MobileAction in ConvertActionToCallToolRequest method
- Maintain backward compatibility while improving package organization
- Clean up code structure by consolidating action-related types in option package

Files affected:
- server/uixt.go: Updated imports and type references
- step.go: Updated imports and ActionResult struct
- step_ui.go: Updated all MobileAction references to option.MobileAction
- uixt/mcp_server.go: Updated ActionTool interface and removed detailed comments
- uixt/mcp_server_test.go: Updated all test cases to use option.MobileAction
- uixt/mcp_tools_*.go: Updated ConvertActionToCallToolRequest method signatures
- uixt/option/action.go: Added MobileAction struct definition
- uixt/sdk.go: Updated ExecuteAction method signature
This commit is contained in:
lilong.129
2025-06-03 18:15:28 +08:00
parent 1cc4b1cf5b
commit bd8cb5abf4
19 changed files with 184 additions and 274 deletions

View File

@@ -1,23 +0,0 @@
package uixt
import (
"github.com/httprunner/httprunner/v5/uixt/option"
)
type MobileAction struct {
Method option.ActionName `json:"method,omitempty" yaml:"method,omitempty"`
Params interface{} `json:"params,omitempty" yaml:"params,omitempty"`
Fn func() `json:"-" yaml:"-"` // used for function action, not serialized
Options *option.ActionOptions `json:"options,omitempty" yaml:"options,omitempty"`
option.ActionOptions
}
func (ma MobileAction) GetOptions() []option.ActionOption {
var actionOptionList []option.ActionOption
// Notice: merge options from ma.Options and ma.ActionOptions
if ma.Options != nil {
actionOptionList = append(actionOptionList, ma.Options.Options()...)
}
actionOptionList = append(actionOptionList, ma.ActionOptions.Options()...)
return actionOptionList
}

View File

@@ -142,61 +142,13 @@ func (s *MCPServer4XTDriver) registerTool(tool ActionTool) {
}
// ActionTool interface defines the contract for MCP tools
//
// This interface standardizes how UI automation actions are exposed through MCP protocol.
// Each tool implementation must provide:
//
// 1. Identity and Documentation:
// - Name(): Unique identifier for the action (e.g., ACTION_TapXY)
// - Description(): Human-readable description for AI models
//
// 2. MCP Integration:
// - Options(): Parameter definitions with validation rules
// - Implement(): Actual execution logic as MCP handler
//
// 3. Legacy Compatibility:
// - ConvertActionToCallToolRequest(): Converts old MobileAction format
//
// Implementation Pattern:
//
// type ToolExample struct{}
//
// func (t *ToolExample) Name() option.ActionName {
// return option.ACTION_Example
// }
//
// func (t *ToolExample) Description() string {
// return "Performs example operation"
// }
//
// func (t *ToolExample) Options() []mcp.ToolOption {
// return []mcp.ToolOption{
// mcp.WithString("param", mcp.Description("Parameter description")),
// }
// }
//
// func (t *ToolExample) Implement() server.ToolHandlerFunc {
// return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// // 1. Setup driver
// // 2. Parse parameters
// // 3. Execute operation
// // 4. Return result
// }
// }
//
// Benefits of this architecture:
// - Complete decoupling between tools
// - Consistent parameter handling
// - Standardized error reporting
// - Easy testing and maintenance
// - Seamless MCP protocol integration
type ActionTool interface {
Name() option.ActionName
Description() string
Options() []mcp.ToolOption
Implement() server.ToolHandlerFunc
// ConvertActionToCallToolRequest converts MobileAction to mcp.CallToolRequest
ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error)
ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error)
// ReturnSchema returns the expected return value schema based on mcp.CallToolResult conventions
ReturnSchema() map[string]string
}
@@ -272,43 +224,6 @@ func getFloat64ValueOrDefault(value float64, defaultValue float64) float64 {
}
// parseActionOptions converts MCP request arguments to ActionOptions struct
//
// This function provides unified parameter parsing for all MCP tools by:
//
// 1. Converting map[string]any arguments to JSON bytes
// 2. Unmarshaling JSON into strongly-typed ActionOptions struct
// 3. Providing automatic validation and type conversion
//
// The ActionOptions struct contains all possible parameters for UI operations:
// - Coordinates: X, Y, FromX, FromY, ToX, ToY
// - Text/Content: Text, Content, AppName, PackageName
// - Timing: Duration, PressDuration, Milliseconds
// - Behavior: AntiRisk, IgnoreNotFoundError, Regex
// - Indices: Index, MaxRetryTimes, TabIndex
// - Device: Platform, Serial, Button, Direction
// - Web: Selector, PhoneNumber, Captcha, Password
// - AI: Prompt
// - Collections: Texts, Params, Points
//
// Parameters:
// - arguments: Raw MCP request arguments as map[string]any
//
// Returns:
// - *option.ActionOptions: Parsed and validated options struct
// - error: Parsing or validation error
//
// Usage:
//
// unifiedReq, err := parseActionOptions(request.Params.Arguments)
// if err != nil {
// return nil, err
// }
// // Use unifiedReq.X, unifiedReq.Y, etc.
//
// Error Handling:
// - JSON marshal errors (invalid argument types)
// - JSON unmarshal errors (type conversion failures)
// - Missing required fields (handled by individual tools)
func parseActionOptions(arguments map[string]any) (*option.ActionOptions, error) {
b, err := json.Marshal(arguments)
if err != nil {

View File

@@ -140,7 +140,7 @@ func TestIgnoreNotFoundErrorOption(t *testing.T) {
option.WithRegex(true),
option.WithTapRandomRect(true),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapByOCR,
Params: "test_text",
ActionOptions: *actionOptions,
@@ -201,7 +201,7 @@ func TestToolListAvailableDevices(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_ListAvailableDevices,
Params: nil,
}
@@ -227,7 +227,7 @@ func TestToolSelectDevice(t *testing.T) {
assert.Len(t, options, 2) // platform and serial
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SelectDevice,
Params: nil,
}
@@ -251,7 +251,7 @@ func TestToolTapXY(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapXY,
Params: []float64{0.5, 0.6},
ActionOptions: option.ActionOptions{
@@ -266,7 +266,7 @@ func TestToolTapXY(t *testing.T) {
assert.Equal(t, 1.5, request.Params.Arguments["duration"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_TapXY,
Params: "invalid",
}
@@ -289,7 +289,7 @@ func TestToolTapAbsXY(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapAbsXY,
Params: []float64{100.0, 200.0},
ActionOptions: option.ActionOptions{
@@ -304,7 +304,7 @@ func TestToolTapAbsXY(t *testing.T) {
assert.Equal(t, 2.0, request.Params.Arguments["duration"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_TapAbsXY,
Params: []float64{100.0}, // missing y coordinate
}
@@ -334,7 +334,7 @@ func TestToolTapByOCR(t *testing.T) {
option.WithRegex(true),
option.WithTapRandomRect(true),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapByOCR,
Params: "test_text",
ActionOptions: *actionOptions,
@@ -350,7 +350,7 @@ func TestToolTapByOCR(t *testing.T) {
assert.Equal(t, true, request.Params.Arguments["tap_random_rect"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_TapByOCR,
Params: 123, // should be string
}
@@ -378,7 +378,7 @@ func TestToolTapByCV(t *testing.T) {
option.WithMaxRetryTimes(2),
option.WithTapRandomRect(true),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapByCV,
Params: nil,
ActionOptions: *actionOptions,
@@ -407,7 +407,7 @@ func TestToolDoubleTapXY(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_DoubleTapXY,
Params: []float64{0.3, 0.7},
}
@@ -418,7 +418,7 @@ func TestToolDoubleTapXY(t *testing.T) {
assert.Equal(t, 0.7, request.Params.Arguments["y"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_DoubleTapXY,
Params: "invalid",
}
@@ -441,7 +441,7 @@ func TestToolSwipe(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with direction params (string)
directionAction := MobileAction{
directionAction := option.MobileAction{
Method: option.ACTION_Swipe,
Params: "up",
ActionOptions: option.ActionOptions{
@@ -457,7 +457,7 @@ func TestToolSwipe(t *testing.T) {
assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"])
// Test ConvertActionToCallToolRequest with coordinate params
coordinateAction := MobileAction{
coordinateAction := option.MobileAction{
Method: option.ACTION_Swipe,
Params: []float64{0.1, 0.2, 0.8, 0.9},
ActionOptions: option.ActionOptions{
@@ -476,7 +476,7 @@ func TestToolSwipe(t *testing.T) {
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_Swipe,
Params: 123, // should be string or []float64
}
@@ -484,7 +484,7 @@ func TestToolSwipe(t *testing.T) {
assert.Error(t, err)
// Test ConvertActionToCallToolRequest with incomplete coordinate params
incompleteAction := MobileAction{
incompleteAction := option.MobileAction{
Method: option.ACTION_Swipe,
Params: []float64{0.1, 0.2}, // missing toX and toY
}
@@ -507,7 +507,7 @@ func TestToolSwipeDirection(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SwipeDirection,
Params: "up",
ActionOptions: option.ActionOptions{
@@ -523,7 +523,7 @@ func TestToolSwipeDirection(t *testing.T) {
assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SwipeDirection,
Params: 123, // should be string
}
@@ -546,7 +546,7 @@ func TestToolSwipeCoordinate(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SwipeCoordinate,
Params: []float64{0.1, 0.2, 0.8, 0.9},
ActionOptions: option.ActionOptions{
@@ -565,7 +565,7 @@ func TestToolSwipeCoordinate(t *testing.T) {
assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SwipeCoordinate,
Params: []float64{0.1, 0.2}, // missing toX and toY
}
@@ -593,7 +593,7 @@ func TestToolSwipeToTapApp(t *testing.T) {
option.WithMaxRetryTimes(3),
option.WithIndex(1),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SwipeToTapApp,
Params: "WeChat",
ActionOptions: *actionOptions,
@@ -607,7 +607,7 @@ func TestToolSwipeToTapApp(t *testing.T) {
assert.Equal(t, 1, request.Params.Arguments["index"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SwipeToTapApp,
Params: 123, // should be string
}
@@ -635,7 +635,7 @@ func TestToolSwipeToTapText(t *testing.T) {
option.WithMaxRetryTimes(2),
option.WithRegex(true),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SwipeToTapText,
Params: "Submit",
ActionOptions: *actionOptions,
@@ -649,7 +649,7 @@ func TestToolSwipeToTapText(t *testing.T) {
assert.Equal(t, true, request.Params.Arguments["regex"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SwipeToTapText,
Params: []int{1, 2, 3}, // should be string
}
@@ -676,7 +676,7 @@ func TestToolSwipeToTapTexts(t *testing.T) {
option.WithIgnoreNotFoundError(true),
option.WithRegex(true),
)
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SwipeToTapTexts,
Params: []string{"OK", "确定", "Submit"},
ActionOptions: *actionOptions,
@@ -692,7 +692,7 @@ func TestToolSwipeToTapTexts(t *testing.T) {
assert.Equal(t, true, request.Params.Arguments["regex"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SwipeToTapTexts,
Params: "single_string", // should be []string
}
@@ -715,7 +715,7 @@ func TestToolDrag(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Drag,
Params: []float64{0.1, 0.2, 0.8, 0.9},
ActionOptions: option.ActionOptions{
@@ -732,7 +732,7 @@ func TestToolDrag(t *testing.T) {
assert.Equal(t, 2500.0, request.Params.Arguments["duration"]) // converted to milliseconds
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_Drag,
Params: []float64{0.1, 0.2}, // missing toX and toY
}
@@ -755,7 +755,7 @@ func TestToolInput(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Input,
Params: "Hello World",
}
@@ -780,7 +780,7 @@ func TestToolScreenShot(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_ScreenShot,
Params: nil,
}
@@ -805,7 +805,7 @@ func TestToolGetScreenSize(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_GetScreenSize,
Params: nil,
}
@@ -830,7 +830,7 @@ func TestToolPressButton(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_PressButton,
Params: "HOME",
}
@@ -840,7 +840,7 @@ func TestToolPressButton(t *testing.T) {
assert.Equal(t, "HOME", request.Params.Arguments["button"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_PressButton,
Params: 123, // should be string
}
@@ -863,7 +863,7 @@ func TestToolHome(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Home,
Params: nil,
}
@@ -888,7 +888,7 @@ func TestToolBack(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Back,
Params: nil,
}
@@ -913,7 +913,7 @@ func TestToolListPackages(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_ListPackages,
Params: nil,
}
@@ -938,7 +938,7 @@ func TestToolLaunchApp(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AppLaunch,
Params: "com.example.app",
}
@@ -948,7 +948,7 @@ func TestToolLaunchApp(t *testing.T) {
assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AppLaunch,
Params: 123, // should be string
}
@@ -971,7 +971,7 @@ func TestToolTerminateApp(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AppTerminate,
Params: "com.example.app",
}
@@ -981,7 +981,7 @@ func TestToolTerminateApp(t *testing.T) {
assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AppTerminate,
Params: []int{1, 2, 3}, // should be string
}
@@ -1004,7 +1004,7 @@ func TestToolAppInstall(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AppInstall,
Params: "https://example.com/app.apk",
}
@@ -1014,7 +1014,7 @@ func TestToolAppInstall(t *testing.T) {
assert.Equal(t, "https://example.com/app.apk", request.Params.Arguments["appUrl"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AppInstall,
Params: 123, // should be string
}
@@ -1037,7 +1037,7 @@ func TestToolAppUninstall(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AppUninstall,
Params: "com.example.app",
}
@@ -1047,7 +1047,7 @@ func TestToolAppUninstall(t *testing.T) {
assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AppUninstall,
Params: 123, // should be string
}
@@ -1070,7 +1070,7 @@ func TestToolAppClear(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AppClear,
Params: "com.example.app",
}
@@ -1080,7 +1080,7 @@ func TestToolAppClear(t *testing.T) {
assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AppClear,
Params: 123, // should be string
}
@@ -1103,7 +1103,7 @@ func TestToolSleep(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Sleep,
Params: 2.5,
}
@@ -1128,7 +1128,7 @@ func TestToolSleepMS(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SleepMS,
Params: int64(1500),
}
@@ -1138,7 +1138,7 @@ func TestToolSleepMS(t *testing.T) {
assert.Equal(t, int64(1500), request.Params.Arguments["milliseconds"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SleepMS,
Params: "invalid", // should be int64
}
@@ -1161,7 +1161,7 @@ func TestToolSleepRandom(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SleepRandom,
Params: []float64{1.0, 3.0},
}
@@ -1174,7 +1174,7 @@ func TestToolSleepRandom(t *testing.T) {
assert.Equal(t, []float64{1.0, 3.0}, params)
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SleepRandom,
Params: "invalid", // should be []float64
}
@@ -1197,7 +1197,7 @@ func TestToolSetIme(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SetIme,
Params: "com.google.android.inputmethod.latin",
}
@@ -1207,7 +1207,7 @@ func TestToolSetIme(t *testing.T) {
assert.Equal(t, "com.google.android.inputmethod.latin", request.Params.Arguments["ime"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SetIme,
Params: 123, // should be string
}
@@ -1230,7 +1230,7 @@ func TestToolGetSource(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_GetSource,
Params: "com.example.app",
}
@@ -1240,7 +1240,7 @@ func TestToolGetSource(t *testing.T) {
assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_GetSource,
Params: 123, // should be string
}
@@ -1263,7 +1263,7 @@ func TestToolClosePopups(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_ClosePopups,
Params: nil,
}
@@ -1288,7 +1288,7 @@ func TestToolAIAction(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_AIAction,
Params: "Click on the login button",
}
@@ -1298,7 +1298,7 @@ func TestToolAIAction(t *testing.T) {
assert.Equal(t, "Click on the login button", request.Params.Arguments["prompt"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_AIAction,
Params: 123, // should be string
}
@@ -1321,7 +1321,7 @@ func TestToolFinished(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_Finished,
Params: "Task completed successfully",
}
@@ -1331,7 +1331,7 @@ func TestToolFinished(t *testing.T) {
assert.Equal(t, "Task completed successfully", request.Params.Arguments["content"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_Finished,
Params: 123, // should be string
}
@@ -1354,7 +1354,7 @@ func TestToolWebLoginNoneUI(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_WebLoginNoneUI,
Params: nil,
}
@@ -1379,7 +1379,7 @@ func TestToolSecondaryClick(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SecondaryClick,
Params: []float64{0.5, 0.6},
}
@@ -1390,7 +1390,7 @@ func TestToolSecondaryClick(t *testing.T) {
assert.Equal(t, 0.6, request.Params.Arguments["y"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SecondaryClick,
Params: "invalid", // should be []float64
}
@@ -1413,7 +1413,7 @@ func TestToolHoverBySelector(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_HoverBySelector,
Params: "#login-button",
}
@@ -1423,7 +1423,7 @@ func TestToolHoverBySelector(t *testing.T) {
assert.Equal(t, "#login-button", request.Params.Arguments["selector"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_HoverBySelector,
Params: 123, // should be string
}
@@ -1446,7 +1446,7 @@ func TestToolTapBySelector(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_TapBySelector,
Params: "//button[@id='submit']",
}
@@ -1456,7 +1456,7 @@ func TestToolTapBySelector(t *testing.T) {
assert.Equal(t, "//button[@id='submit']", request.Params.Arguments["selector"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_TapBySelector,
Params: 123, // should be string
}
@@ -1479,7 +1479,7 @@ func TestToolSecondaryClickBySelector(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_SecondaryClickBySelector,
Params: ".context-menu-trigger",
}
@@ -1489,7 +1489,7 @@ func TestToolSecondaryClickBySelector(t *testing.T) {
assert.Equal(t, ".context-menu-trigger", request.Params.Arguments["selector"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_SecondaryClickBySelector,
Params: 123, // should be string
}
@@ -1512,7 +1512,7 @@ func TestToolWebCloseTab(t *testing.T) {
assert.NotNil(t, options)
// Test ConvertActionToCallToolRequest with valid params
action := MobileAction{
action := option.MobileAction{
Method: option.ACTION_WebCloseTab,
Params: 1,
}
@@ -1522,7 +1522,7 @@ func TestToolWebCloseTab(t *testing.T) {
assert.Equal(t, 1, request.Params.Arguments["tabIndex"])
// Test ConvertActionToCallToolRequest with invalid params
invalidAction := MobileAction{
invalidAction := option.MobileAction{
Method: option.ACTION_WebCloseTab,
Params: "invalid", // should be int
}
@@ -1539,7 +1539,7 @@ func TestPreMarkOperationConfiguration(t *testing.T) {
assert.NotNil(t, tapTool)
// Test conversion with pre_mark_operation enabled
actionWithPreMark := MobileAction{
actionWithPreMark := option.MobileAction{
Method: option.ACTION_TapXY,
Params: []float64{0.5, 0.5},
ActionOptions: *option.NewActionOptions(option.WithPreMarkOperation(true)),
@@ -1550,7 +1550,7 @@ func TestPreMarkOperationConfiguration(t *testing.T) {
assert.Equal(t, true, request.Params.Arguments["pre_mark_operation"])
// Test conversion without pre_mark_operation
actionWithoutPreMark := MobileAction{
actionWithoutPreMark := option.MobileAction{
Method: option.ACTION_TapXY,
Params: []float64{0.5, 0.5},
ActionOptions: *option.NewActionOptions(option.WithPreMarkOperation(false)),

View File

@@ -49,7 +49,7 @@ func (t *ToolAIAction) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolAIAction) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolAIAction) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if prompt, ok := action.Params.(string); ok {
arguments := map[string]any{
"prompt": prompt,
@@ -95,7 +95,7 @@ func (t *ToolFinished) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolFinished) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolFinished) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if reason, ok := action.Params.(string); ok {
arguments := map[string]any{
"content": reason,

View File

@@ -41,7 +41,7 @@ func (t *ToolListPackages) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolListPackages) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolListPackages) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -94,7 +94,7 @@ func (t *ToolLaunchApp) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolLaunchApp) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolLaunchApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if packageName, ok := action.Params.(string); ok {
arguments := map[string]any{
"packageName": packageName,
@@ -154,7 +154,7 @@ func (t *ToolTerminateApp) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTerminateApp) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTerminateApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if packageName, ok := action.Params.(string); ok {
arguments := map[string]any{
"packageName": packageName,
@@ -207,7 +207,7 @@ func (t *ToolAppInstall) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolAppInstall) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolAppInstall) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if appUrl, ok := action.Params.(string); ok {
arguments := map[string]any{
"appUrl": appUrl,
@@ -263,7 +263,7 @@ func (t *ToolAppUninstall) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolAppUninstall) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolAppUninstall) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if packageName, ok := action.Params.(string); ok {
arguments := map[string]any{
"packageName": packageName,
@@ -319,7 +319,7 @@ func (t *ToolAppClear) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolAppClear) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolAppClear) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if packageName, ok := action.Params.(string); ok {
arguments := map[string]any{
"packageName": packageName,

View File

@@ -50,7 +50,7 @@ func (t *ToolPressButton) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolPressButton) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolPressButton) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if button, ok := action.Params.(string); ok {
arguments := map[string]any{
"button": button,
@@ -101,7 +101,7 @@ func (t *ToolHome) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolHome) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolHome) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -145,7 +145,7 @@ func (t *ToolBack) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolBack) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolBack) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}

View File

@@ -64,7 +64,7 @@ func (t *ToolListAvailableDevices) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolListAvailableDevices) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolListAvailableDevices) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -105,7 +105,7 @@ func (t *ToolSelectDevice) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSelectDevice) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSelectDevice) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}

View File

@@ -53,7 +53,7 @@ func (t *ToolInput) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolInput) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolInput) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
text := fmt.Sprintf("%v", action.Params)
arguments := map[string]any{
"text": text,
@@ -107,7 +107,7 @@ func (t *ToolSetIme) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSetIme) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSetIme) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if ime, ok := action.Params.(string); ok {
arguments := map[string]any{
"ime": ime,

View File

@@ -43,7 +43,7 @@ func (t *ToolScreenShot) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolScreenShot) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolScreenShot) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -88,7 +88,7 @@ func (t *ToolGetScreenSize) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolGetScreenSize) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolGetScreenSize) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -139,7 +139,7 @@ func (t *ToolGetSource) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolGetSource) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolGetSource) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if packageName, ok := action.Params.(string); ok {
arguments := map[string]any{
"packageName": packageName,

View File

@@ -45,7 +45,7 @@ func (t *ToolSwipe) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipe) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipe) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
// Check if params is a string (direction-based swipe)
if _, ok := action.Params.(string); ok {
// Delegate to ToolSwipeDirection but use our tool name
@@ -159,7 +159,7 @@ func (t *ToolSwipeDirection) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipeDirection) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipeDirection) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
// Handle direction swipe like "up", "down", "left", "right"
if direction, ok := action.Params.(string); ok {
arguments := map[string]any{
@@ -252,7 +252,7 @@ func (t *ToolSwipeCoordinate) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
arguments := map[string]any{
"from_x": paramSlice[0],
@@ -341,7 +341,7 @@ func (t *ToolSwipeToTapApp) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipeToTapApp) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipeToTapApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if appName, ok := action.Params.(string); ok {
arguments := map[string]any{
"appName": appName,
@@ -420,7 +420,7 @@ func (t *ToolSwipeToTapText) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipeToTapText) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipeToTapText) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if text, ok := action.Params.(string); ok {
arguments := map[string]any{
"text": text,
@@ -499,7 +499,7 @@ func (t *ToolSwipeToTapTexts) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSwipeToTapTexts) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSwipeToTapTexts) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
var texts []string
if textsSlice, ok := action.Params.([]string); ok {
texts = textsSlice
@@ -587,7 +587,7 @@ func (t *ToolDrag) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolDrag) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolDrag) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if paramSlice, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(paramSlice) == 4 {
arguments := map[string]any{
"from_x": paramSlice[0],

View File

@@ -64,7 +64,7 @@ func (t *ToolTapXY) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTapXY) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTapXY) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(params) == 2 {
x, y := params[0], params[1]
arguments := map[string]any{
@@ -148,7 +148,7 @@ func (t *ToolTapAbsXY) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTapAbsXY) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTapAbsXY) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(params) == 2 {
x, y := params[0], params[1]
arguments := map[string]any{
@@ -233,7 +233,7 @@ func (t *ToolTapByOCR) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTapByOCR) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTapByOCR) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if text, ok := action.Params.(string); ok {
arguments := map[string]any{
"text": text,
@@ -304,7 +304,7 @@ func (t *ToolTapByCV) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTapByCV) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTapByCV) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
// For TapByCV, the original action might not have params but relies on options
arguments := map[string]any{
"imagePath": "", // Will be handled by the tool based on UI types
@@ -364,7 +364,7 @@ func (t *ToolDoubleTapXY) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolDoubleTapXY) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolDoubleTapXY) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(params) == 2 {
x, y := params[0], params[1]
arguments := map[string]any{

View File

@@ -64,7 +64,7 @@ func (t *ToolSleep) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSleep) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSleep) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
arguments := map[string]any{
"seconds": action.Params,
}
@@ -114,7 +114,7 @@ func (t *ToolSleepMS) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSleepMS) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSleepMS) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
var milliseconds int64
if param, ok := action.Params.(json.Number); ok {
milliseconds, _ = param.Int64()
@@ -167,7 +167,7 @@ func (t *ToolSleepRandom) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSleepRandom) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSleepRandom) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil {
arguments := map[string]any{
"params": params,
@@ -219,7 +219,7 @@ func (t *ToolClosePopups) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolClosePopups) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolClosePopups) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}

View File

@@ -56,7 +56,7 @@ func (t *ToolWebLoginNoneUI) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolWebLoginNoneUI) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolWebLoginNoneUI) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
}
@@ -111,7 +111,7 @@ func (t *ToolSecondaryClick) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSecondaryClick) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSecondaryClick) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if params, err := builtin.ConvertToFloat64Slice(action.Params); err == nil && len(params) == 2 {
arguments := map[string]any{
"x": params[0],
@@ -169,7 +169,7 @@ func (t *ToolHoverBySelector) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolHoverBySelector) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolHoverBySelector) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if selector, ok := action.Params.(string); ok {
arguments := map[string]any{
"selector": selector,
@@ -225,7 +225,7 @@ func (t *ToolTapBySelector) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolTapBySelector) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolTapBySelector) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if selector, ok := action.Params.(string); ok {
arguments := map[string]any{
"selector": selector,
@@ -281,7 +281,7 @@ func (t *ToolSecondaryClickBySelector) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolSecondaryClickBySelector) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolSecondaryClickBySelector) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
if selector, ok := action.Params.(string); ok {
arguments := map[string]any{
"selector": selector,
@@ -347,7 +347,7 @@ func (t *ToolWebCloseTab) Implement() server.ToolHandlerFunc {
}
}
func (t *ToolWebCloseTab) ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) {
func (t *ToolWebCloseTab) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
var tabIndex int
if param, ok := action.Params.(json.Number); ok {
paramInt64, _ := param.Int64()

View File

@@ -13,6 +13,24 @@ import (
"github.com/rs/zerolog/log"
)
type MobileAction struct {
Method ActionName `json:"method,omitempty" yaml:"method,omitempty"`
Params interface{} `json:"params,omitempty" yaml:"params,omitempty"`
Fn func() `json:"-" yaml:"-"` // used for function action, not serialized
Options *ActionOptions `json:"options,omitempty" yaml:"options,omitempty"`
ActionOptions
}
func (ma MobileAction) GetOptions() []ActionOption {
var actionOptionList []ActionOption
// Notice: merge options from ma.Options and ma.ActionOptions
if ma.Options != nil {
actionOptionList = append(actionOptionList, ma.Options.Options()...)
}
actionOptionList = append(actionOptionList, ma.ActionOptions.Options()...)
return actionOptionList
}
type ActionName string
const (

View File

@@ -87,7 +87,7 @@ func (c *MCPClient4XTDriver) GetToolByAction(actionName option.ActionName) Actio
return c.Server.GetToolByAction(actionName)
}
func (dExt *XTDriver) ExecuteAction(ctx context.Context, action MobileAction) (err error) {
func (dExt *XTDriver) ExecuteAction(ctx context.Context, action option.MobileAction) (err error) {
// Find the corresponding tool for this action method
tool := dExt.client.Server.GetToolByAction(action.Method)
if tool == nil {