mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-07 04:52:47 +08:00
feat: 重构 MCP 工具导出逻辑并完善返回值类型系统
This commit is contained in:
@@ -1 +1 @@
|
||||
v5.0.0-beta-2505300045
|
||||
v5.0.0-beta-2505310028
|
||||
|
||||
175
mcphost/dump.go
175
mcphost/dump.go
@@ -9,20 +9,30 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v5/uixt"
|
||||
"github.com/httprunner/httprunner/v5/uixt/option"
|
||||
)
|
||||
|
||||
// MCPToolRecord represents a single tool record in the database
|
||||
// Each record contains detailed information about a tool and its server
|
||||
type MCPToolRecord struct {
|
||||
ToolID string `json:"tool_id"` // Unique identifier for the tool record
|
||||
ServerName string `json:"mcp_server"` // Name of the MCP server
|
||||
ToolName string `json:"tool_name"` // Name of the tool
|
||||
Description string `json:"description"` // Tool description
|
||||
Parameters string `json:"parameters"` // Tool input parameters in JSON format
|
||||
Returns string `json:"returns"` // Tool return value format in JSON format
|
||||
CreatedAt time.Time `json:"created_at"` // Record creation time
|
||||
LastUpdatedAt time.Time `json:"last_updated_at"` // Record last update time
|
||||
ToolID string `json:"tool_id"` // Unique identifier for the tool record
|
||||
BizID string `json:"biz_id"` // Business ID of the tool
|
||||
VisibleRange int `json:"visible_range"` // Visible range of the tool, 0: visible to biz, 1: visible to all
|
||||
ToolType string `json:"tool_type"` // Type of the tool
|
||||
ServerName string `json:"mcp_server"` // Name of the MCP server
|
||||
ToolName string `json:"tool_name"` // Name of the tool
|
||||
Description string `json:"description"` // Tool description
|
||||
Parameters string `json:"parameters"` // Tool input parameters in JSON format
|
||||
Returns string `json:"return_desc"` // Tool return value format in JSON format
|
||||
TeardownPair string `json:"teardown_pair"` // Teardown pair of the tool
|
||||
Examples string `json:"examples"` // Examples of the tool
|
||||
SupportPatterns string `json:"support_patterns"` // Support pattern of the tool
|
||||
CreatedAt time.Time `json:"created_at"` // Record creation time
|
||||
LastUpdatedAt time.Time `json:"last_updated_at"` // Record last update time
|
||||
}
|
||||
|
||||
// DocStringInfo contains the parsed information from a Python docstring
|
||||
@@ -109,8 +119,13 @@ func extractDocStringInfo(docstring string) DocStringInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
// ActionToolProvider defines the interface for MCP servers that provide ActionTool implementations
|
||||
type ActionToolProvider interface {
|
||||
GetToolByAction(actionName option.ActionName) uixt.ActionTool
|
||||
}
|
||||
|
||||
// ConvertToolsToRecords converts []MCPTools to a list of database records
|
||||
func ConvertToolsToRecords(tools []MCPTools) []MCPToolRecord {
|
||||
func (host *MCPHost) ConvertToolsToRecords(tools []MCPTools) []MCPToolRecord {
|
||||
var records []MCPToolRecord
|
||||
now := time.Now()
|
||||
|
||||
@@ -121,36 +136,7 @@ func ConvertToolsToRecords(tools []MCPTools) []MCPToolRecord {
|
||||
}
|
||||
|
||||
for _, tool := range mcpTools.Tools {
|
||||
// Generate unique ID by combining server name and tool name
|
||||
id := fmt.Sprintf("%s__%s", mcpTools.ServerName, tool.Name)
|
||||
|
||||
// Extract docstring information
|
||||
info := extractDocStringInfo(tool.Description)
|
||||
|
||||
// Convert parameters and returns to JSON
|
||||
paramsJSON, err := sonic.MarshalString(info.Parameters)
|
||||
if err != nil {
|
||||
log.Warn().Interface("params", info.Parameters).Err(err).Msg("failed to marshal parameters to JSON")
|
||||
paramsJSON = "{}"
|
||||
}
|
||||
|
||||
returnsJSON, err := sonic.MarshalString(info.Returns)
|
||||
if err != nil {
|
||||
log.Warn().Interface("returns", info.Returns).Err(err).Msg("failed to marshal returns to JSON")
|
||||
returnsJSON = "{}"
|
||||
}
|
||||
|
||||
record := MCPToolRecord{
|
||||
ToolID: id,
|
||||
ServerName: mcpTools.ServerName,
|
||||
ToolName: tool.Name,
|
||||
Description: info.Description,
|
||||
Parameters: paramsJSON,
|
||||
Returns: returnsJSON,
|
||||
CreatedAt: now,
|
||||
LastUpdatedAt: now,
|
||||
}
|
||||
|
||||
record := host.convertSingleToolToRecord(mcpTools.ServerName, tool, now)
|
||||
records = append(records, record)
|
||||
}
|
||||
}
|
||||
@@ -158,12 +144,121 @@ func ConvertToolsToRecords(tools []MCPTools) []MCPToolRecord {
|
||||
return records
|
||||
}
|
||||
|
||||
// convertSingleToolToRecord converts a single MCP tool to a database record
|
||||
func (host *MCPHost) convertSingleToolToRecord(serverName string, tool mcp.Tool, timestamp time.Time) MCPToolRecord {
|
||||
// Generate unique ID
|
||||
id := fmt.Sprintf("%s__%s", serverName, tool.Name)
|
||||
|
||||
// Extract description from docstring
|
||||
info := extractDocStringInfo(tool.Description)
|
||||
|
||||
// Extract parameters
|
||||
paramsJSON := host.extractParameters(tool, info)
|
||||
|
||||
// Extract returns
|
||||
returnsJSON := host.extractReturns(serverName, tool.Name, info)
|
||||
|
||||
return MCPToolRecord{
|
||||
ToolID: id,
|
||||
VisibleRange: 1,
|
||||
ToolType: "edge",
|
||||
ServerName: serverName,
|
||||
ToolName: tool.Name,
|
||||
Description: info.Description,
|
||||
Parameters: paramsJSON,
|
||||
Returns: returnsJSON,
|
||||
CreatedAt: timestamp,
|
||||
LastUpdatedAt: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
// extractParameters extracts parameter information from tool schema or docstring
|
||||
func (host *MCPHost) extractParameters(tool mcp.Tool, info DocStringInfo) string {
|
||||
// Priority 1: Extract from InputSchema.Properties
|
||||
if len(tool.InputSchema.Properties) > 0 {
|
||||
return host.extractParametersFromSchema(tool.InputSchema.Properties)
|
||||
}
|
||||
|
||||
// Priority 2: Extract from docstring
|
||||
if len(info.Parameters) > 0 {
|
||||
return host.marshalToJSON(info.Parameters, "docstring parameters")
|
||||
}
|
||||
|
||||
return "{}"
|
||||
}
|
||||
|
||||
// extractParametersFromSchema extracts parameters from MCP tool input schema
|
||||
func (host *MCPHost) extractParametersFromSchema(properties map[string]interface{}) string {
|
||||
schemaParams := make(map[string]string)
|
||||
|
||||
for propName, propValue := range properties {
|
||||
propMap, ok := propValue.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
description := host.getPropertyDescription(propMap)
|
||||
schemaParams[propName] = description
|
||||
}
|
||||
|
||||
return host.marshalToJSON(schemaParams, "schema parameters")
|
||||
}
|
||||
|
||||
// getPropertyDescription extracts description from property map
|
||||
func (host *MCPHost) getPropertyDescription(propMap map[string]interface{}) string {
|
||||
if desc, exists := propMap["description"]; exists {
|
||||
if descStr, ok := desc.(string); ok {
|
||||
return descStr
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to type information
|
||||
if propType, exists := propMap["type"]; exists {
|
||||
if typeStr, ok := propType.(string); ok {
|
||||
return fmt.Sprintf("Parameter of type %s", typeStr)
|
||||
}
|
||||
}
|
||||
|
||||
return "Parameter"
|
||||
}
|
||||
|
||||
// extractReturns extracts return value information from ActionTool or docstring
|
||||
func (host *MCPHost) extractReturns(serverName, toolName string, info DocStringInfo) string {
|
||||
// Priority 1: Get from ActionTool interface if available
|
||||
if actionToolProvider := host.getActionToolProvider(serverName); actionToolProvider != nil {
|
||||
if actionTool := actionToolProvider.GetToolByAction(option.ActionName(toolName)); actionTool != nil {
|
||||
returnSchema := actionTool.ReturnSchema()
|
||||
if len(returnSchema) > 0 {
|
||||
return host.marshalToJSON(returnSchema, "return schema")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 2: Use docstring returns as fallback
|
||||
if len(info.Returns) > 0 {
|
||||
return host.marshalToJSON(info.Returns, "docstring returns")
|
||||
}
|
||||
|
||||
return "{}"
|
||||
}
|
||||
|
||||
// marshalToJSON marshals data to JSON string with error handling
|
||||
func (host *MCPHost) marshalToJSON(data interface{}, dataType string) string {
|
||||
jsonBytes, err := sonic.MarshalString(data)
|
||||
if err != nil {
|
||||
log.Warn().Interface("data", data).Err(err).
|
||||
Msgf("failed to marshal %s to JSON", dataType)
|
||||
return "{}"
|
||||
}
|
||||
return jsonBytes
|
||||
}
|
||||
|
||||
// ExportToolsToJSON dumps MCP tools to JSON file
|
||||
func (h *MCPHost) ExportToolsToJSON(ctx context.Context, dumpPath string) error {
|
||||
// get all tools
|
||||
tools := h.GetTools(ctx)
|
||||
// convert to records
|
||||
records := ConvertToolsToRecords(tools)
|
||||
records := h.ConvertToolsToRecords(tools)
|
||||
// convert to JSON
|
||||
recordsJSON, err := sonic.MarshalIndent(records, "", " ")
|
||||
if err != nil {
|
||||
|
||||
@@ -124,6 +124,11 @@ func TestExtractDocStringInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertToolsToRecords(t *testing.T) {
|
||||
// Create a mock MCPHost for testing
|
||||
host := &MCPHost{
|
||||
connections: make(map[string]*Connection),
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
tools []MCPTools
|
||||
@@ -152,7 +157,7 @@ func TestConvertToolsToRecords(t *testing.T) {
|
||||
},
|
||||
want: []MCPToolRecord{
|
||||
{
|
||||
ToolID: "weather_get_alerts",
|
||||
ToolID: "weather__get_alerts",
|
||||
ServerName: "weather",
|
||||
ToolName: "get_alerts",
|
||||
Description: "Get weather alerts for a US state.",
|
||||
@@ -184,7 +189,7 @@ func TestConvertToolsToRecords(t *testing.T) {
|
||||
},
|
||||
want: []MCPToolRecord{
|
||||
{
|
||||
ToolID: "ui_swipe",
|
||||
ToolID: "ui__swipe",
|
||||
ServerName: "ui",
|
||||
ToolName: "swipe",
|
||||
Description: "Do screen swipe action.",
|
||||
@@ -192,7 +197,7 @@ func TestConvertToolsToRecords(t *testing.T) {
|
||||
Returns: "{}",
|
||||
},
|
||||
{
|
||||
ToolID: "ui_tap",
|
||||
ToolID: "ui__tap",
|
||||
ServerName: "ui",
|
||||
ToolName: "tap",
|
||||
Description: "Tap on screen at specified position.",
|
||||
@@ -201,11 +206,47 @@ func TestConvertToolsToRecords(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "convert tool with InputSchema",
|
||||
tools: []MCPTools{
|
||||
{
|
||||
ServerName: "test",
|
||||
Tools: []mcp.Tool{
|
||||
{
|
||||
Name: "test_tool",
|
||||
Description: "Test tool with input schema",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]interface{}{
|
||||
"param1": map[string]interface{}{
|
||||
"type": "string",
|
||||
"description": "First parameter",
|
||||
},
|
||||
"param2": map[string]interface{}{
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []MCPToolRecord{
|
||||
{
|
||||
ToolID: "test__test_tool",
|
||||
ServerName: "test",
|
||||
ToolName: "test_tool",
|
||||
Description: "Test tool with input schema",
|
||||
Parameters: `{"param1":"First parameter","param2":"Parameter of type number"}`,
|
||||
Returns: "{}",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ConvertToolsToRecords(tt.tools)
|
||||
got := host.ConvertToolsToRecords(tt.tools)
|
||||
|
||||
// Compare each record
|
||||
require.Equal(t, len(tt.want), len(got))
|
||||
@@ -235,3 +276,179 @@ func TestConvertToolsToRecords(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtractParameters tests the extractParameters method
|
||||
func TestExtractParameters(t *testing.T) {
|
||||
host := &MCPHost{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
tool mcp.Tool
|
||||
info DocStringInfo
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "extract from InputSchema",
|
||||
tool: mcp.Tool{
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Properties: map[string]interface{}{
|
||||
"param1": map[string]interface{}{
|
||||
"type": "string",
|
||||
"description": "First parameter",
|
||||
},
|
||||
"param2": map[string]interface{}{
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
info: DocStringInfo{Parameters: map[string]string{"old": "old param"}},
|
||||
expected: `{"param1":"First parameter","param2":"Parameter of type number"}`,
|
||||
},
|
||||
{
|
||||
name: "fallback to docstring",
|
||||
tool: mcp.Tool{},
|
||||
info: DocStringInfo{
|
||||
Parameters: map[string]string{
|
||||
"param": "parameter description",
|
||||
},
|
||||
},
|
||||
expected: `{"param":"parameter description"}`,
|
||||
},
|
||||
{
|
||||
name: "empty parameters",
|
||||
tool: mcp.Tool{},
|
||||
info: DocStringInfo{},
|
||||
expected: "{}",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := host.extractParameters(tt.tool, tt.info)
|
||||
assert.Equal(t, tt.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtractReturns tests the extractReturns method
|
||||
func TestExtractReturns(t *testing.T) {
|
||||
host := &MCPHost{
|
||||
connections: make(map[string]*Connection),
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
serverName string
|
||||
toolName string
|
||||
info DocStringInfo
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "fallback to docstring returns",
|
||||
serverName: "unknown_server",
|
||||
toolName: "unknown_tool",
|
||||
info: DocStringInfo{
|
||||
Returns: map[string]string{
|
||||
"result": "operation result",
|
||||
"error": "error message",
|
||||
},
|
||||
},
|
||||
expected: `{"error":"error message","result":"operation result"}`,
|
||||
},
|
||||
{
|
||||
name: "empty returns",
|
||||
serverName: "unknown_server",
|
||||
toolName: "unknown_tool",
|
||||
info: DocStringInfo{},
|
||||
expected: "{}",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := host.extractReturns(tt.serverName, tt.toolName, tt.info)
|
||||
assert.Equal(t, tt.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetPropertyDescription tests the getPropertyDescription method
|
||||
func TestGetPropertyDescription(t *testing.T) {
|
||||
host := &MCPHost{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
propMap map[string]interface{}
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "with description",
|
||||
propMap: map[string]interface{}{
|
||||
"type": "string",
|
||||
"description": "Parameter description",
|
||||
},
|
||||
expected: "Parameter description",
|
||||
},
|
||||
{
|
||||
name: "without description, with type",
|
||||
propMap: map[string]interface{}{
|
||||
"type": "number",
|
||||
},
|
||||
expected: "Parameter of type number",
|
||||
},
|
||||
{
|
||||
name: "without description and type",
|
||||
propMap: map[string]interface{}{},
|
||||
expected: "Parameter",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := host.getPropertyDescription(tt.propMap)
|
||||
assert.Equal(t, tt.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestMarshalToJSON tests the marshalToJSON method
|
||||
func TestMarshalToJSON(t *testing.T) {
|
||||
host := &MCPHost{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
data interface{}
|
||||
dataType string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "valid map",
|
||||
data: map[string]string{
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
},
|
||||
dataType: "test data",
|
||||
expected: `{"key1":"value1","key2":"value2"}`,
|
||||
},
|
||||
{
|
||||
name: "empty map",
|
||||
data: map[string]string{},
|
||||
dataType: "test data",
|
||||
expected: "{}",
|
||||
},
|
||||
{
|
||||
name: "invalid data (channel)",
|
||||
data: make(chan int),
|
||||
dataType: "test data",
|
||||
expected: "{}",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := host.marshalToJSON(tt.data, tt.dataType)
|
||||
assert.Equal(t, tt.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,3 +558,18 @@ func (h *MCPHost) forceCloseAll() {
|
||||
delete(h.connections, name)
|
||||
}
|
||||
}
|
||||
|
||||
// getActionToolProvider returns an ActionToolProvider for the given server name if available
|
||||
// This method checks if the MCP server implements the ActionToolProvider interface
|
||||
func (h *MCPHost) getActionToolProvider(serverName string) ActionToolProvider {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
|
||||
if conn, exists := h.connections[serverName]; exists {
|
||||
// Check if the client directly implements ActionToolProvider interface
|
||||
if actionToolProvider, ok := conn.Client.(ActionToolProvider); ok {
|
||||
return actionToolProvider
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ func (s *MCPServer4XTDriver) registerTools() {
|
||||
s.registerTool(&ToolTapByCV{}) // tap by CV
|
||||
s.registerTool(&ToolDoubleTapXY{}) // double tap xy
|
||||
|
||||
// Swipe Tool
|
||||
// Swipe Tools
|
||||
s.registerTool(&ToolSwipe{}) // generic swipe, auto-detect direction or coordinate
|
||||
s.registerTool(&ToolSwipeDirection{}) // swipe direction, up/down/left/right
|
||||
s.registerTool(&ToolSwipeCoordinate{}) // swipe coordinate, [fromX, fromY, toX, toY]
|
||||
@@ -337,7 +337,7 @@ func (s *MCPServer4XTDriver) registerTools() {
|
||||
s.registerTool(&ToolAppUninstall{}) // AppUninstall
|
||||
s.registerTool(&ToolAppClear{}) // AppClear
|
||||
|
||||
// Sleep Tool
|
||||
// Sleep Tools
|
||||
s.registerTool(&ToolSleep{})
|
||||
s.registerTool(&ToolSleepMS{})
|
||||
s.registerTool(&ToolSleepRandom{})
|
||||
@@ -432,6 +432,8 @@ type ActionTool interface {
|
||||
Implement() server.ToolHandlerFunc
|
||||
// ConvertActionToCallToolRequest converts MobileAction to mcp.CallToolRequest
|
||||
ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error)
|
||||
// ReturnSchema returns the expected return value schema based on mcp.CallToolResult conventions
|
||||
ReturnSchema() map[string]string
|
||||
}
|
||||
|
||||
// buildMCPCallToolRequest is a helper function to build mcp.CallToolRequest
|
||||
@@ -505,6 +507,13 @@ func (t *ToolListAvailableDevices) ConvertActionToCallToolRequest(action MobileA
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolListAvailableDevices) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"androidDevices": "[]string: List of Android device serial numbers",
|
||||
"iosDevices": "[]string: List of iOS device UDIDs",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSelectDevice implements the select_device tool call.
|
||||
type ToolSelectDevice struct{}
|
||||
|
||||
@@ -539,6 +548,12 @@ func (t *ToolSelectDevice) ConvertActionToCallToolRequest(action MobileAction) (
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolSelectDevice) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message with selected device UUID",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolTapXY implements the tap_xy tool call.
|
||||
//
|
||||
// This tool performs touch/click operations at specified relative coordinates on the device screen.
|
||||
@@ -656,6 +671,12 @@ func (t *ToolTapXY) ConvertActionToCallToolRequest(action MobileAction) (mcp.Cal
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid tap params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolTapXY) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming tap operation at specified coordinates",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolTapAbsXY implements the tap_abs_xy tool call.
|
||||
type ToolTapAbsXY struct{}
|
||||
|
||||
@@ -734,6 +755,19 @@ func (t *ToolTapAbsXY) ConvertActionToCallToolRequest(action MobileAction) (mcp.
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid tap abs params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolTapAbsXY) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming tap operation at absolute coordinates",
|
||||
}
|
||||
}
|
||||
|
||||
// defaultReturnSchema provides a standard return schema for most tools
|
||||
func defaultReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the operation was completed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolTapByOCR implements the tap_ocr tool call.
|
||||
type ToolTapByOCR struct{}
|
||||
|
||||
@@ -800,6 +834,12 @@ func (t *ToolTapByOCR) ConvertActionToCallToolRequest(action MobileAction) (mcp.
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid tap by OCR params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolTapByOCR) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the operation was completed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolTapByCV implements the tap_cv tool call.
|
||||
type ToolTapByCV struct{}
|
||||
|
||||
@@ -863,6 +903,10 @@ func (t *ToolTapByCV) ConvertActionToCallToolRequest(action MobileAction) (mcp.C
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolTapByCV) ReturnSchema() map[string]string {
|
||||
return defaultReturnSchema()
|
||||
}
|
||||
|
||||
// ToolDoubleTapXY implements the double_tap_xy tool call.
|
||||
type ToolDoubleTapXY struct{}
|
||||
|
||||
@@ -919,6 +963,10 @@ func (t *ToolDoubleTapXY) ConvertActionToCallToolRequest(action MobileAction) (m
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid double tap params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolDoubleTapXY) ReturnSchema() map[string]string {
|
||||
return defaultReturnSchema()
|
||||
}
|
||||
|
||||
// ToolListPackages implements the list_packages tool call.
|
||||
type ToolListPackages struct{}
|
||||
|
||||
@@ -954,6 +1002,12 @@ func (t *ToolListPackages) ConvertActionToCallToolRequest(action MobileAction) (
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolListPackages) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"packages": "[]string: List of installed app package names on the device",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolLaunchApp implements the launch_app tool call.
|
||||
type ToolLaunchApp struct{}
|
||||
|
||||
@@ -1007,6 +1061,10 @@ func (t *ToolLaunchApp) ConvertActionToCallToolRequest(action MobileAction) (mcp
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid app launch params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolLaunchApp) ReturnSchema() map[string]string {
|
||||
return defaultReturnSchema()
|
||||
}
|
||||
|
||||
// ToolTerminateApp implements the terminate_app tool call.
|
||||
type ToolTerminateApp struct{}
|
||||
|
||||
@@ -1063,6 +1121,10 @@ func (t *ToolTerminateApp) ConvertActionToCallToolRequest(action MobileAction) (
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid app terminate params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolTerminateApp) ReturnSchema() map[string]string {
|
||||
return defaultReturnSchema()
|
||||
}
|
||||
|
||||
// ToolScreenShot implements the screenshot tool call.
|
||||
type ToolScreenShot struct{}
|
||||
|
||||
@@ -1100,6 +1162,14 @@ func (t *ToolScreenShot) ConvertActionToCallToolRequest(action MobileAction) (mc
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolScreenShot) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"image": "string: Base64 encoded screenshot image in JPEG format",
|
||||
"name": "string: Image name identifier (typically 'screenshot')",
|
||||
"type": "string: MIME type of the image (image/jpeg)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolGetScreenSize implements the get_screen_size tool call.
|
||||
type ToolGetScreenSize struct{}
|
||||
|
||||
@@ -1137,6 +1207,14 @@ func (t *ToolGetScreenSize) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolGetScreenSize) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"width": "int: Screen width in pixels",
|
||||
"height": "int: Screen height in pixels",
|
||||
"message": "string: Formatted message with screen dimensions",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolPressButton implements the press_button tool call.
|
||||
type ToolPressButton struct{}
|
||||
|
||||
@@ -1186,6 +1264,13 @@ func (t *ToolPressButton) ConvertActionToCallToolRequest(action MobileAction) (m
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid press button params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolPressButton) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the button press operation",
|
||||
"button": "string: Name of the button that was pressed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipe implements the generic swipe tool call.
|
||||
// It automatically determines whether to use direction-based or coordinate-based swipe
|
||||
// based on the params type.
|
||||
@@ -1249,6 +1334,17 @@ func (t *ToolSwipe) ConvertActionToCallToolRequest(action MobileAction) (mcp.Cal
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe params: %v, expected string direction or [fromX, fromY, toX, toY] coordinates", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSwipe) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the swipe operation",
|
||||
"direction": "string: Direction of swipe (for directional swipes)",
|
||||
"fromX": "float64: Starting X coordinate (for coordinate-based swipes)",
|
||||
"fromY": "float64: Starting Y coordinate (for coordinate-based swipes)",
|
||||
"toX": "float64: Ending X coordinate (for coordinate-based swipes)",
|
||||
"toY": "float64: Ending Y coordinate (for coordinate-based swipes)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipeDirection implements the swipe_direction tool call.
|
||||
type ToolSwipeDirection struct{}
|
||||
|
||||
@@ -1344,6 +1440,13 @@ func (t *ToolSwipeDirection) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSwipeDirection) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the directional swipe",
|
||||
"direction": "string: Direction that was swiped (up/down/left/right)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipeCoordinate implements the swipe_coordinate tool call.
|
||||
type ToolSwipeCoordinate struct{}
|
||||
|
||||
@@ -1432,6 +1535,16 @@ func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action MobileAction
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe advanced params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSwipeCoordinate) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the coordinate-based swipe",
|
||||
"fromX": "float64: Starting X coordinate of the swipe",
|
||||
"fromY": "float64: Starting Y coordinate of the swipe",
|
||||
"toX": "float64: Ending X coordinate of the swipe",
|
||||
"toY": "float64: Ending Y coordinate of the swipe",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipeToTapApp implements the swipe_to_tap_app tool call.
|
||||
type ToolSwipeToTapApp struct{}
|
||||
|
||||
@@ -1501,6 +1614,13 @@ func (t *ToolSwipeToTapApp) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe to tap app params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSwipeToTapApp) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the app was found and tapped",
|
||||
"appName": "string: Name of the app that was found and tapped",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipeToTapText implements the swipe_to_tap_text tool call.
|
||||
type ToolSwipeToTapText struct{}
|
||||
|
||||
@@ -1573,6 +1693,13 @@ func (t *ToolSwipeToTapText) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe to tap text params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSwipeToTapText) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the text was found and tapped",
|
||||
"text": "string: Text content that was found and tapped",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSwipeToTapTexts implements the swipe_to_tap_texts tool call.
|
||||
type ToolSwipeToTapTexts struct{}
|
||||
|
||||
@@ -1650,6 +1777,14 @@ func (t *ToolSwipeToTapTexts) ConvertActionToCallToolRequest(action MobileAction
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolSwipeToTapTexts) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming one of the texts was found and tapped",
|
||||
"texts": "[]string: List of text options that were searched for",
|
||||
"foundText": "string: The specific text that was actually found and tapped",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolDrag implements the drag tool call.
|
||||
type ToolDrag struct{}
|
||||
|
||||
@@ -1732,6 +1867,16 @@ func (t *ToolDrag) ConvertActionToCallToolRequest(action MobileAction) (mcp.Call
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid drag parameters: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolDrag) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming the drag operation",
|
||||
"fromX": "float64: Starting X coordinate of the drag",
|
||||
"fromY": "float64: Starting Y coordinate of the drag",
|
||||
"toX": "float64: Ending X coordinate of the drag",
|
||||
"toY": "float64: Ending Y coordinate of the drag",
|
||||
}
|
||||
}
|
||||
|
||||
// extractActionOptionsToArguments extracts action options and adds them to arguments map
|
||||
// This is a generic helper that can be used by multiple tools
|
||||
func extractActionOptionsToArguments(actionOptions []option.ActionOption, arguments map[string]any) {
|
||||
@@ -1817,6 +1962,12 @@ func (t *ToolHome) ConvertActionToCallToolRequest(action MobileAction) (mcp.Call
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolHome) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming home button was pressed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolBack implements the back tool call.
|
||||
type ToolBack struct{}
|
||||
|
||||
@@ -1855,6 +2006,12 @@ func (t *ToolBack) ConvertActionToCallToolRequest(action MobileAction) (mcp.Call
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolBack) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming back button was pressed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolInput implements the input tool call.
|
||||
type ToolInput struct{}
|
||||
|
||||
@@ -1906,6 +2063,13 @@ func (t *ToolInput) ConvertActionToCallToolRequest(action MobileAction) (mcp.Cal
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolInput) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming text was input",
|
||||
"text": "string: Text content that was input into the field",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolWebLoginNoneUI implements the web_login_none_ui tool call.
|
||||
type ToolWebLoginNoneUI struct{}
|
||||
|
||||
@@ -1954,6 +2118,13 @@ func (t *ToolWebLoginNoneUI) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolWebLoginNoneUI) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming web login was completed",
|
||||
"loginResult": "object: Result of the login operation (success/failure details)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolAppInstall implements the app_install tool call.
|
||||
type ToolAppInstall struct{}
|
||||
|
||||
@@ -2003,6 +2174,13 @@ func (t *ToolAppInstall) ConvertActionToCallToolRequest(action MobileAction) (mc
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid app install params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolAppInstall) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming app installation",
|
||||
"appUrl": "string: URL or path of the app that was installed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolAppUninstall implements the app_uninstall tool call.
|
||||
type ToolAppUninstall struct{}
|
||||
|
||||
@@ -2052,6 +2230,13 @@ func (t *ToolAppUninstall) ConvertActionToCallToolRequest(action MobileAction) (
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid app uninstall params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolAppUninstall) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming app uninstallation",
|
||||
"packageName": "string: Package name of the app that was uninstalled",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolAppClear implements the app_clear tool call.
|
||||
type ToolAppClear struct{}
|
||||
|
||||
@@ -2101,6 +2286,13 @@ func (t *ToolAppClear) ConvertActionToCallToolRequest(action MobileAction) (mcp.
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid app clear params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolAppClear) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming app data and cache were cleared",
|
||||
"packageName": "string: Package name of the app that was cleared",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSecondaryClick implements the secondary_click tool call.
|
||||
type ToolSecondaryClick struct{}
|
||||
|
||||
@@ -2156,6 +2348,14 @@ func (t *ToolSecondaryClick) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid secondary click params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSecondaryClick) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming secondary click (right-click) operation",
|
||||
"x": "float64: X coordinate where secondary click was performed",
|
||||
"y": "float64: Y coordinate where secondary click was performed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolHoverBySelector implements the hover_by_selector tool call.
|
||||
type ToolHoverBySelector struct{}
|
||||
|
||||
@@ -2205,6 +2405,13 @@ func (t *ToolHoverBySelector) ConvertActionToCallToolRequest(action MobileAction
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid hover by selector params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolHoverBySelector) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming hover operation",
|
||||
"selector": "string: CSS selector or XPath of the element that was hovered over",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolTapBySelector implements the tap_by_selector tool call.
|
||||
type ToolTapBySelector struct{}
|
||||
|
||||
@@ -2254,6 +2461,13 @@ func (t *ToolTapBySelector) ConvertActionToCallToolRequest(action MobileAction)
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid tap by selector params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolTapBySelector) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming tap operation",
|
||||
"selector": "string: CSS selector or XPath of the element that was tapped",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSecondaryClickBySelector implements the secondary_click_by_selector tool call.
|
||||
type ToolSecondaryClickBySelector struct{}
|
||||
|
||||
@@ -2303,6 +2517,13 @@ func (t *ToolSecondaryClickBySelector) ConvertActionToCallToolRequest(action Mob
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid secondary click by selector params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSecondaryClickBySelector) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming secondary click operation",
|
||||
"selector": "string: CSS selector or XPath of the element that was right-clicked",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolWebCloseTab implements the web_close_tab tool call.
|
||||
type ToolWebCloseTab struct{}
|
||||
|
||||
@@ -2370,6 +2591,13 @@ func (t *ToolWebCloseTab) ConvertActionToCallToolRequest(action MobileAction) (m
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolWebCloseTab) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming browser tab was closed",
|
||||
"tabIndex": "int: Index of the tab that was closed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSetIme implements the set_ime tool call.
|
||||
type ToolSetIme struct{}
|
||||
|
||||
@@ -2419,6 +2647,13 @@ func (t *ToolSetIme) ConvertActionToCallToolRequest(action MobileAction) (mcp.Ca
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid set ime params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSetIme) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming IME was set",
|
||||
"ime": "string: Input method editor that was set",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolGetSource implements the get_source tool call.
|
||||
type ToolGetSource struct{}
|
||||
|
||||
@@ -2468,6 +2703,14 @@ func (t *ToolGetSource) ConvertActionToCallToolRequest(action MobileAction) (mcp
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid get source params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolGetSource) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming UI source was retrieved",
|
||||
"packageName": "string: Package name of the app whose source was retrieved",
|
||||
"source": "string: UI hierarchy/source tree data in XML or JSON format",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSleep implements the sleep tool call.
|
||||
type ToolSleep struct{}
|
||||
|
||||
@@ -2526,6 +2769,13 @@ func (t *ToolSleep) ConvertActionToCallToolRequest(action MobileAction) (mcp.Cal
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolSleep) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming sleep operation completed",
|
||||
"seconds": "float64: Duration in seconds that was slept",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSleepMS implements the sleep_ms tool call.
|
||||
type ToolSleepMS struct{}
|
||||
|
||||
@@ -2577,6 +2827,13 @@ func (t *ToolSleepMS) ConvertActionToCallToolRequest(action MobileAction) (mcp.C
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolSleepMS) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming sleep operation completed",
|
||||
"milliseconds": "int64: Duration in milliseconds that was slept",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSleepRandom implements the sleep_random tool call.
|
||||
type ToolSleepRandom struct{}
|
||||
|
||||
@@ -2618,6 +2875,14 @@ func (t *ToolSleepRandom) ConvertActionToCallToolRequest(action MobileAction) (m
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid sleep random params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSleepRandom) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming random sleep operation completed",
|
||||
"params": "[]float64: Parameters used for random duration calculation",
|
||||
"actualDuration": "float64: Actual duration that was slept (in seconds)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolClosePopups implements the close_popups tool call.
|
||||
type ToolClosePopups struct{}
|
||||
|
||||
@@ -2656,6 +2921,13 @@ func (t *ToolClosePopups) ConvertActionToCallToolRequest(action MobileAction) (m
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolClosePopups) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming popups were closed",
|
||||
"popupsClosed": "int: Number of popup windows or dialogs that were closed",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolAIAction implements the ai_action tool call.
|
||||
type ToolAIAction struct{}
|
||||
|
||||
@@ -2705,6 +2977,14 @@ func (t *ToolAIAction) ConvertActionToCallToolRequest(action MobileAction) (mcp.
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid AI action params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolAIAction) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming AI action was performed",
|
||||
"prompt": "string: Natural language prompt that was processed",
|
||||
"actionTaken": "string: Description of the specific action that was taken by AI",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolFinished implements the finished tool call.
|
||||
type ToolFinished struct{}
|
||||
|
||||
@@ -2743,6 +3023,14 @@ func (t *ToolFinished) ConvertActionToCallToolRequest(action MobileAction) (mcp.
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid finished params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolFinished) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming task completion",
|
||||
"content": "string: Completion reason or result description",
|
||||
"taskCompleted": "bool: Boolean indicating task was successfully finished",
|
||||
}
|
||||
}
|
||||
|
||||
func getFloat64ValueOrDefault(value float64, defaultValue float64) float64 {
|
||||
if value == 0 {
|
||||
return defaultValue
|
||||
|
||||
@@ -69,6 +69,7 @@ type ActionTool interface {
|
||||
Options() []mcp.ToolOption // MCP 选项定义
|
||||
Implement() server.ToolHandlerFunc // 工具实现逻辑
|
||||
ConvertActionToCallToolRequest(action MobileAction) (mcp.CallToolRequest, error) // 动作转换
|
||||
ReturnSchema() map[string]string // 返回值结构描述
|
||||
}
|
||||
```
|
||||
|
||||
@@ -100,6 +101,12 @@ func (t *ToolTapXY) Implement() server.ToolHandlerFunc {
|
||||
return mcp.NewToolResultText("操作成功"), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ToolTapXY) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming tap operation at specified coordinates",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 统一参数处理
|
||||
@@ -153,6 +160,20 @@ if err != nil {
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 返回值结构化描述
|
||||
|
||||
每个工具都提供详细的返回值类型信息:
|
||||
|
||||
```go
|
||||
func (t *ToolScreenShot) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"image": "string: Base64 encoded screenshot image in JPEG format",
|
||||
"name": "string: Image name identifier (typically 'screenshot')",
|
||||
"type": "string: MIME type of the image (image/jpeg)",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 如何扩展接入新工具
|
||||
|
||||
### 步骤 1: 定义工具结构体
|
||||
@@ -256,7 +277,20 @@ func (t *ToolLongPress) ConvertActionToCallToolRequest(action MobileAction) (mcp
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤 5: 注册工具
|
||||
### 步骤 5: 定义返回值结构
|
||||
|
||||
```go
|
||||
func (t *ToolLongPress) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming long press operation",
|
||||
"x": "float64: X coordinate where long press was performed",
|
||||
"y": "float64: Y coordinate where long press was performed",
|
||||
"duration": "float64: Duration of the long press in seconds",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤 6: 注册工具
|
||||
|
||||
在 `registerTools()` 方法中添加新工具:
|
||||
|
||||
@@ -271,7 +305,7 @@ func (s *MCPServer4XTDriver) registerTools() {
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤 6: 添加单元测试
|
||||
### 步骤 7: 添加单元测试
|
||||
|
||||
```go
|
||||
func TestToolLongPress(t *testing.T) {
|
||||
@@ -285,6 +319,11 @@ func TestToolLongPress(t *testing.T) {
|
||||
options := tool.Options()
|
||||
assert.NotEmpty(t, options)
|
||||
|
||||
// 测试返回值结构
|
||||
returnSchema := tool.ReturnSchema()
|
||||
assert.Contains(t, returnSchema["message"], "string:")
|
||||
assert.Contains(t, returnSchema["x"], "float64:")
|
||||
|
||||
// 测试动作转换
|
||||
action := MobileAction{
|
||||
Method: option.ACTION_LongPress,
|
||||
@@ -360,6 +399,17 @@ if unifiedReq.AntiRisk {
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 返回值类型规范
|
||||
```go
|
||||
// 标准返回值类型前缀
|
||||
"message": "string: 描述信息"
|
||||
"x": "float64: X坐标值"
|
||||
"count": "int: 数量"
|
||||
"success": "bool: 成功状态"
|
||||
"items": "[]string: 字符串数组"
|
||||
"data": "object: 复杂对象"
|
||||
```
|
||||
|
||||
## 🚀 高级特性
|
||||
|
||||
### 1. 反作弊支持
|
||||
@@ -396,7 +446,11 @@ for _, point := range unifiedReq.Points {
|
||||
#### list_available_devices
|
||||
**功能**: 发现所有可用的设备和模拟器
|
||||
**参数**: 无
|
||||
**返回**: JSON 格式的设备列表
|
||||
**返回值类型**:
|
||||
- `androidDevices` ([]string): Android 设备序列号列表
|
||||
- `iosDevices` ([]string): iOS 设备 UDID 列表
|
||||
|
||||
**返回示例**:
|
||||
```json
|
||||
{
|
||||
"androidDevices": ["emulator-5554", "device-serial"],
|
||||
@@ -410,6 +464,9 @@ for _, point := range unifiedReq.Points {
|
||||
- `platform` (string): "android" | "ios" | "web" | "harmony"
|
||||
- `serial` (string): 设备序列号或 UDID
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 包含选中设备 UUID 的成功消息
|
||||
|
||||
---
|
||||
|
||||
### 👆 触摸操作工具
|
||||
@@ -422,6 +479,9 @@ for _, point := range unifiedReq.Points {
|
||||
- `duration` (number, 可选): 点击持续时间(秒)
|
||||
- `anti_risk` (boolean, 可选): 启用反作弊
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认在指定坐标点击操作的成功消息
|
||||
|
||||
#### tap_abs_xy
|
||||
**功能**: 在绝对像素坐标点击
|
||||
**参数**:
|
||||
@@ -430,6 +490,9 @@ for _, point := range unifiedReq.Points {
|
||||
- `duration` (number, 可选): 点击持续时间(秒)
|
||||
- `anti_risk` (boolean, 可选): 启用反作弊
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认在绝对坐标点击操作的成功消息
|
||||
|
||||
#### tap_ocr
|
||||
**功能**: 通过 OCR 识别文本并点击
|
||||
**参数**:
|
||||
@@ -437,18 +500,27 @@ for _, point := range unifiedReq.Points {
|
||||
- `ignore_NotFoundError` (boolean, 可选): 忽略未找到错误
|
||||
- `regex` (boolean, 可选): 使用正则表达式匹配
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认操作完成的成功消息
|
||||
|
||||
#### tap_cv
|
||||
**功能**: 通过计算机视觉识别图像并点击
|
||||
**参数**:
|
||||
- `imagePath` (string): 模板图像路径
|
||||
- `threshold` (number, 可选): 匹配阈值
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认操作完成的成功消息
|
||||
|
||||
#### double_tap_xy
|
||||
**功能**: 在指定坐标双击
|
||||
**参数**:
|
||||
- `x` (number): X 坐标
|
||||
- `y` (number): Y 坐标
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认操作完成的成功消息
|
||||
|
||||
---
|
||||
|
||||
### 🔄 手势操作工具
|
||||
@@ -457,6 +529,14 @@ for _, point := range unifiedReq.Points {
|
||||
**功能**: 通用滑动 (自动检测方向或坐标)
|
||||
**参数**: 支持方向滑动或坐标滑动两种模式
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认滑动操作的成功消息
|
||||
- `direction` (string): 滑动方向 (方向滑动模式)
|
||||
- `fromX` (float64): 起始 X 坐标 (坐标滑动模式)
|
||||
- `fromY` (float64): 起始 Y 坐标 (坐标滑动模式)
|
||||
- `toX` (float64): 结束 X 坐标 (坐标滑动模式)
|
||||
- `toY` (float64): 结束 Y 坐标 (坐标滑动模式)
|
||||
|
||||
##### 方向滑动模式:
|
||||
- `direction` (string): "up" | "down" | "left" | "right"
|
||||
- `duration` (number, 可选): 滑动持续时间
|
||||
@@ -468,6 +548,34 @@ for _, point := range unifiedReq.Points {
|
||||
- `to_x` (number): 结束 X 坐标
|
||||
- `to_y` (number): 结束 Y 坐标
|
||||
|
||||
#### swipe_direction
|
||||
**功能**: 方向滑动
|
||||
**参数**:
|
||||
- `direction` (string): "up" | "down" | "left" | "right"
|
||||
- `duration` (number, 可选): 滑动持续时间
|
||||
- `press_duration` (number, 可选): 按压持续时间
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认方向滑动的成功消息
|
||||
- `direction` (string): 滑动的方向 (up/down/left/right)
|
||||
|
||||
#### swipe_coordinate
|
||||
**功能**: 坐标滑动
|
||||
**参数**:
|
||||
- `from_x` (number): 起始 X 坐标
|
||||
- `from_y` (number): 起始 Y 坐标
|
||||
- `to_x` (number): 结束 X 坐标
|
||||
- `to_y` (number): 结束 Y 坐标
|
||||
- `duration` (number, 可选): 滑动持续时间
|
||||
- `press_duration` (number, 可选): 按压持续时间
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认坐标滑动的成功消息
|
||||
- `fromX` (float64): 滑动起始 X 坐标
|
||||
- `fromY` (float64): 滑动起始 Y 坐标
|
||||
- `toX` (float64): 滑动结束 X 坐标
|
||||
- `toY` (float64): 滑动结束 Y 坐标
|
||||
|
||||
#### drag
|
||||
**功能**: 拖拽操作
|
||||
**参数**:
|
||||
@@ -477,6 +585,13 @@ for _, point := range unifiedReq.Points {
|
||||
- `to_y` (number): 结束 Y 坐标
|
||||
- `duration` (number, 可选): 拖拽持续时间(毫秒)
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认拖拽操作的成功消息
|
||||
- `fromX` (float64): 拖拽起始 X 坐标
|
||||
- `fromY` (float64): 拖拽起始 Y 坐标
|
||||
- `toX` (float64): 拖拽结束 X 坐标
|
||||
- `toY` (float64): 拖拽结束 Y 坐标
|
||||
|
||||
#### swipe_to_tap_app
|
||||
**功能**: 滑动查找并点击应用
|
||||
**参数**:
|
||||
@@ -484,6 +599,10 @@ for _, point := range unifiedReq.Points {
|
||||
- `max_retry_times` (number, 可选): 最大重试次数
|
||||
- `ignore_NotFoundError` (boolean, 可选): 忽略未找到错误
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认找到并点击应用的成功消息
|
||||
- `appName` (string): 找到并点击的应用名称
|
||||
|
||||
#### swipe_to_tap_text
|
||||
**功能**: 滑动查找并点击文本
|
||||
**参数**:
|
||||
@@ -491,12 +610,21 @@ for _, point := range unifiedReq.Points {
|
||||
- `max_retry_times` (number, 可选): 最大重试次数
|
||||
- `regex` (boolean, 可选): 使用正则表达式
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认找到并点击文本的成功消息
|
||||
- `text` (string): 找到并点击的文本内容
|
||||
|
||||
#### swipe_to_tap_texts
|
||||
**功能**: 滑动查找并点击多个文本中的一个
|
||||
**参数**:
|
||||
- `texts` (array): 文本数组
|
||||
- `max_retry_times` (number, 可选): 最大重试次数
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认找到并点击其中一个文本的成功消息
|
||||
- `texts` ([]string): 搜索的文本选项列表
|
||||
- `foundText` (string): 实际找到并点击的特定文本
|
||||
|
||||
---
|
||||
|
||||
### ⌨️ 输入操作工具
|
||||
@@ -506,6 +634,10 @@ for _, point := range unifiedReq.Points {
|
||||
**参数**:
|
||||
- `text` (string): 要输入的文本
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认文本输入的成功消息
|
||||
- `text` (string): 输入到字段中的文本内容
|
||||
|
||||
#### press_button
|
||||
**功能**: 按设备按键
|
||||
**参数**:
|
||||
@@ -513,14 +645,24 @@ for _, point := range unifiedReq.Points {
|
||||
- Android: "BACK", "HOME", "VOLUME_UP", "VOLUME_DOWN", "ENTER"
|
||||
- iOS: "HOME", "VOLUME_UP", "VOLUME_DOWN"
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认按键操作的成功消息
|
||||
- `button` (string): 被按下的按键名称
|
||||
|
||||
#### home
|
||||
**功能**: 按 Home 键
|
||||
**参数**: 无
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认 Home 键被按下的成功消息
|
||||
|
||||
#### back
|
||||
**功能**: 按返回键 (仅 Android)
|
||||
**参数**: 无
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认返回键被按下的成功消息
|
||||
|
||||
---
|
||||
|
||||
### 📱 应用管理工具
|
||||
@@ -529,31 +671,52 @@ for _, point := range unifiedReq.Points {
|
||||
**功能**: 列出设备上所有应用包名
|
||||
**参数**: 无
|
||||
|
||||
**返回值类型**:
|
||||
- `packages` ([]string): 设备上已安装应用包名列表
|
||||
|
||||
#### app_launch
|
||||
**功能**: 启动应用
|
||||
**参数**:
|
||||
- `packageName` (string): 应用包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认操作完成的成功消息
|
||||
|
||||
#### app_terminate
|
||||
**功能**: 终止应用
|
||||
**参数**:
|
||||
- `packageName` (string): 应用包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认操作完成的成功消息
|
||||
|
||||
#### app_install
|
||||
**功能**: 安装应用
|
||||
**参数**:
|
||||
- `appUrl` (string): APK/IPA 文件路径或 URL
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认应用安装的成功消息
|
||||
- `appUrl` (string): 安装的应用 URL 或路径
|
||||
|
||||
#### app_uninstall
|
||||
**功能**: 卸载应用
|
||||
**参数**:
|
||||
- `packageName` (string): 应用包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认应用卸载的成功消息
|
||||
- `packageName` (string): 被卸载的应用包名
|
||||
|
||||
#### app_clear
|
||||
**功能**: 清除应用数据
|
||||
**参数**:
|
||||
- `packageName` (string): 应用包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认应用数据和缓存被清除的成功消息
|
||||
- `packageName` (string): 被清除的应用包名
|
||||
|
||||
---
|
||||
|
||||
### 📸 屏幕操作工具
|
||||
@@ -561,18 +724,31 @@ for _, point := range unifiedReq.Points {
|
||||
#### screenshot
|
||||
**功能**: 截取屏幕截图
|
||||
**参数**: 无
|
||||
**返回**: Base64 编码的图像数据
|
||||
|
||||
**返回值类型**:
|
||||
- `image` (string): JPEG 格式的 Base64 编码截图图像
|
||||
- `name` (string): 图像名称标识符 (通常为 'screenshot')
|
||||
- `type` (string): 图像的 MIME 类型 (image/jpeg)
|
||||
|
||||
#### get_screen_size
|
||||
**功能**: 获取屏幕尺寸
|
||||
**参数**: 无
|
||||
**返回**: 屏幕宽度和高度 (像素)
|
||||
|
||||
**返回值类型**:
|
||||
- `width` (int): 屏幕宽度 (像素)
|
||||
- `height` (int): 屏幕高度 (像素)
|
||||
- `message` (string): 包含屏幕尺寸的格式化消息
|
||||
|
||||
#### get_source
|
||||
**功能**: 获取 UI 层次结构
|
||||
**参数**:
|
||||
- `packageName` (string, 可选): 指定应用包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认 UI 源码获取的成功消息
|
||||
- `packageName` (string): 获取源码的应用包名
|
||||
- `source` (string): XML 或 JSON 格式的 UI 层次/源码树数据
|
||||
|
||||
---
|
||||
|
||||
### ⏱️ 时间控制工具
|
||||
@@ -582,16 +758,29 @@ for _, point := range unifiedReq.Points {
|
||||
**参数**:
|
||||
- `seconds` (number): 等待秒数
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认睡眠操作完成的成功消息
|
||||
- `seconds` (float64): 睡眠的持续时间 (秒)
|
||||
|
||||
#### sleep_ms
|
||||
**功能**: 等待指定毫秒数
|
||||
**参数**:
|
||||
- `milliseconds` (number): 等待毫秒数
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认睡眠操作完成的成功消息
|
||||
- `milliseconds` (int64): 睡眠的持续时间 (毫秒)
|
||||
|
||||
#### sleep_random
|
||||
**功能**: 随机等待
|
||||
**参数**:
|
||||
- `params` (array): 随机参数数组
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认随机睡眠操作完成的成功消息
|
||||
- `params` ([]float64): 用于随机持续时间计算的参数
|
||||
- `actualDuration` (float64): 实际睡眠的持续时间 (秒)
|
||||
|
||||
---
|
||||
|
||||
### 🛠️ 实用工具
|
||||
@@ -601,10 +790,18 @@ for _, point := range unifiedReq.Points {
|
||||
**参数**:
|
||||
- `ime` (string): 输入法包名
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认 IME 设置的成功消息
|
||||
- `ime` (string): 设置的输入法编辑器
|
||||
|
||||
#### close_popups
|
||||
**功能**: 关闭弹窗
|
||||
**参数**: 无
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认弹窗关闭的成功消息
|
||||
- `popupsClosed` (int): 关闭的弹窗或对话框数量
|
||||
|
||||
---
|
||||
|
||||
### 🌐 Web 操作工具
|
||||
@@ -617,32 +814,57 @@ for _, point := range unifiedReq.Points {
|
||||
- `captcha` (string, 可选): 验证码
|
||||
- `password` (string, 可选): 密码
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认 Web 登录完成的成功消息
|
||||
- `loginResult` (object): 登录操作的结果 (成功/失败详情)
|
||||
|
||||
#### secondary_click
|
||||
**功能**: 右键点击
|
||||
**参数**:
|
||||
- `x` (number): X 坐标
|
||||
- `y` (number): Y 坐标
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认辅助点击 (右键) 操作的成功消息
|
||||
- `x` (float64): 执行辅助点击的 X 坐标
|
||||
- `y` (float64): 执行辅助点击的 Y 坐标
|
||||
|
||||
#### hover_by_selector
|
||||
**功能**: 悬停在选择器元素上
|
||||
**参数**:
|
||||
- `selector` (string): CSS 选择器或 XPath
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认悬停操作的成功消息
|
||||
- `selector` (string): 悬停元素的 CSS 选择器或 XPath
|
||||
|
||||
#### tap_by_selector
|
||||
**功能**: 点击选择器元素
|
||||
**参数**:
|
||||
- `selector` (string): CSS 选择器或 XPath
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认点击操作的成功消息
|
||||
- `selector` (string): 被点击元素的 CSS 选择器或 XPath
|
||||
|
||||
#### secondary_click_by_selector
|
||||
**功能**: 右键点击选择器元素
|
||||
**参数**:
|
||||
- `selector` (string): CSS 选择器或 XPath
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认辅助点击操作的成功消息
|
||||
- `selector` (string): 被右键点击元素的 CSS 选择器或 XPath
|
||||
|
||||
#### web_close_tab
|
||||
**功能**: 关闭浏览器标签页
|
||||
**参数**:
|
||||
- `tabIndex` (number): 标签页索引
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认浏览器标签页关闭的成功消息
|
||||
- `tabIndex` (int): 被关闭的标签页索引
|
||||
|
||||
---
|
||||
|
||||
### 🤖 AI 操作工具
|
||||
@@ -652,11 +874,21 @@ for _, point := range unifiedReq.Points {
|
||||
**参数**:
|
||||
- `prompt` (string): 自然语言指令
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认 AI 操作执行的成功消息
|
||||
- `prompt` (string): 处理的自然语言提示
|
||||
- `actionTaken` (string): AI 执行的具体操作描述
|
||||
|
||||
#### finished
|
||||
**功能**: 标记任务完成
|
||||
**参数**:
|
||||
- `content` (string): 完成信息
|
||||
|
||||
**返回值类型**:
|
||||
- `message` (string): 确认任务完成的成功消息
|
||||
- `content` (string): 完成原因或结果描述
|
||||
- `taskCompleted` (bool): 指示任务成功完成的布尔值
|
||||
|
||||
---
|
||||
|
||||
### 📋 通用参数说明
|
||||
@@ -754,3 +986,23 @@ for _, point := range unifiedReq.Points {
|
||||
4. **平台差异**: 不同平台支持的功能可能有差异
|
||||
5. **错误处理**: 建议启用适当的错误忽略选项
|
||||
6. **性能考虑**: 避免过于频繁的操作,适当添加等待时间
|
||||
7. **返回值类型**: 所有返回值都包含明确的类型信息,便于 AI 模型理解和处理
|
||||
|
||||
### 📊 返回值类型系统
|
||||
|
||||
HttpRunner MCP Server 为所有工具提供了完整的返回值类型描述,采用 `类型: 描述` 的格式:
|
||||
|
||||
#### 支持的数据类型
|
||||
- **string**: 文本消息、名称、描述等
|
||||
- **int**: 整数值如屏幕宽度、高度、标签索引等
|
||||
- **int64**: 长整型如毫秒数
|
||||
- **float64**: 浮点数如坐标值、时间等
|
||||
- **bool**: 布尔值如任务完成状态
|
||||
- **[]string**: 字符串数组如设备列表、文本选项等
|
||||
- **object**: 复杂对象如登录结果
|
||||
|
||||
#### 类型信息的作用
|
||||
1. **AI 模型理解**: 帮助 AI 模型正确解析和使用返回值
|
||||
2. **开发调试**: 为开发者提供清晰的接口文档
|
||||
3. **类型安全**: 确保数据类型的一致性和可预测性
|
||||
4. **自动化测试**: 支持基于类型的自动化验证
|
||||
|
||||
@@ -82,6 +82,11 @@ func (c *MCPClient4XTDriver) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetToolByAction implements ActionToolProvider interface
|
||||
func (c *MCPClient4XTDriver) GetToolByAction(actionName option.ActionName) ActionTool {
|
||||
return c.Server.GetToolByAction(actionName)
|
||||
}
|
||||
|
||||
func (dExt *XTDriver) ExecuteAction(ctx context.Context, action MobileAction) (err error) {
|
||||
// Find the corresponding tool for this action method
|
||||
tool := dExt.client.Server.GetToolByAction(action.Method)
|
||||
|
||||
Reference in New Issue
Block a user