From 7393f7aab3dbe2e11530815033de3929df4bcf70 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 18:18:34 +0800 Subject: [PATCH 1/6] refactor: BuildMCPCallToolRequest --- internal/version/VERSION | 2 +- uixt/driver_ext_ai.go | 25 ++++++++----------------- uixt/mcp_server.go | 5 ++++- uixt/mcp_tools_ai.go | 20 ++++---------------- uixt/mcp_tools_app.go | 17 +++++++++-------- uixt/mcp_tools_button.go | 11 ++++++----- uixt/mcp_tools_device.go | 11 ++++++----- uixt/mcp_tools_input.go | 11 +++++++---- uixt/mcp_tools_screen.go | 6 +++--- uixt/mcp_tools_swipe.go | 36 ++++++------------------------------ uixt/mcp_tools_touch.go | 26 +++++--------------------- uixt/mcp_tools_utility.go | 8 ++++---- uixt/mcp_tools_web.go | 23 ++++++----------------- 13 files changed, 69 insertions(+), 132 deletions(-) diff --git a/internal/version/VERSION b/internal/version/VERSION index 43e8ef92..bce4fd6e 100644 --- a/internal/version/VERSION +++ b/internal/version/VERSION @@ -1 +1 @@ -v5.0.0-250702 +v5.0.0-250703 diff --git a/uixt/driver_ext_ai.go b/uixt/driver_ext_ai.go index e44f5020..97d9393e 100644 --- a/uixt/driver_ext_ai.go +++ b/uixt/driver_ext_ai.go @@ -5,7 +5,6 @@ import ( "time" "github.com/cloudwego/eino/schema" - "github.com/mark3labs/mcp-go/mcp" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -313,24 +312,16 @@ func (dExt *XTDriver) invokeToolCall(ctx context.Context, toolCall schema.ToolCa return err } - // Merge StartToGoal options into tool call arguments - // This ensures options like PreMarkOperation are passed to specific tool implementations - extractActionOptionsToArguments(opts, arguments) - - // Execute the action - req := mcp.CallToolRequest{ - Params: struct { - Name string `json:"name"` - Arguments map[string]any `json:"arguments,omitempty"` - Meta *struct { - ProgressToken mcp.ProgressToken `json:"progressToken,omitempty"` - } `json:"_meta,omitempty"` - }{ - Name: toolCall.Function.Name, - Arguments: arguments, - }, + // Create a MobileAction with options to reuse BuildMCPCallToolRequest + action := option.MobileAction{ + Options: option.NewActionOptions(opts...), } + req := BuildMCPCallToolRequest( + option.ActionName(toolCall.Function.Name), + arguments, + action, + ) _, err = dExt.client.CallTool(ctx, req) if err != nil { return err diff --git a/uixt/mcp_server.go b/uixt/mcp_server.go index 2c721fff..087b9f4c 100644 --- a/uixt/mcp_server.go +++ b/uixt/mcp_server.go @@ -158,7 +158,10 @@ type ActionTool interface { } // BuildMCPCallToolRequest is a helper function to build mcp.CallToolRequest -func BuildMCPCallToolRequest(toolName option.ActionName, arguments map[string]any) mcp.CallToolRequest { +func BuildMCPCallToolRequest(toolName option.ActionName, arguments map[string]any, action option.MobileAction) mcp.CallToolRequest { + // Automatically extract action options and add them to arguments + extractActionOptionsToArguments(action.GetOptions(), arguments) + return mcp.CallToolRequest{ Params: struct { Name string `json:"name"` diff --git a/uixt/mcp_tools_ai.go b/uixt/mcp_tools_ai.go index 7acf31e9..d969f67a 100644 --- a/uixt/mcp_tools_ai.go +++ b/uixt/mcp_tools_ai.go @@ -62,11 +62,7 @@ func (t *ToolStartToGoal) ConvertActionToCallToolRequest(action option.MobileAct arguments := map[string]any{ "prompt": prompt, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid start to goal params: %v", action.Params) } @@ -122,11 +118,7 @@ func (t *ToolAIAction) ConvertActionToCallToolRequest(action option.MobileAction arguments := map[string]any{ "prompt": prompt, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid AI action params: %v", action.Params) } @@ -187,11 +179,7 @@ func (t *ToolAIQuery) ConvertActionToCallToolRequest(action option.MobileAction) arguments := map[string]any{ "prompt": prompt, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid AI query params: %v", action.Params) } @@ -237,7 +225,7 @@ func (t *ToolFinished) ConvertActionToCallToolRequest(action option.MobileAction arguments := map[string]any{ "content": reason, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid finished params: %v", action.Params) } diff --git a/uixt/mcp_tools_app.go b/uixt/mcp_tools_app.go index 3c9e8c77..6afe3f19 100644 --- a/uixt/mcp_tools_app.go +++ b/uixt/mcp_tools_app.go @@ -4,10 +4,11 @@ import ( "context" "fmt" - "github.com/httprunner/httprunner/v5/uixt/option" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" "github.com/rs/zerolog/log" + + "github.com/httprunner/httprunner/v5/uixt/option" ) // ToolListPackages implements the list_packages tool call. @@ -53,7 +54,7 @@ func (t *ToolListPackages) Implement() server.ToolHandlerFunc { } func (t *ToolListPackages) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolLaunchApp implements the launch_app tool call. @@ -109,7 +110,7 @@ func (t *ToolLaunchApp) ConvertActionToCallToolRequest(action option.MobileActio arguments := map[string]any{ "packageName": packageName, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid app launch params: %v", action.Params) } @@ -174,7 +175,7 @@ func (t *ToolTerminateApp) ConvertActionToCallToolRequest(action option.MobileAc arguments := map[string]any{ "packageName": packageName, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid app terminate params: %v", action.Params) } @@ -228,7 +229,7 @@ func (t *ToolAppInstall) ConvertActionToCallToolRequest(action option.MobileActi arguments := map[string]any{ "appUrl": appUrl, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid app install params: %v", action.Params) } @@ -282,7 +283,7 @@ func (t *ToolAppUninstall) ConvertActionToCallToolRequest(action option.MobileAc arguments := map[string]any{ "packageName": packageName, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid app uninstall params: %v", action.Params) } @@ -336,7 +337,7 @@ func (t *ToolAppClear) ConvertActionToCallToolRequest(action option.MobileAction arguments := map[string]any{ "packageName": packageName, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid app clear params: %v", action.Params) } @@ -385,5 +386,5 @@ func (t *ToolGetForegroundApp) Implement() server.ToolHandlerFunc { } func (t *ToolGetForegroundApp) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } diff --git a/uixt/mcp_tools_button.go b/uixt/mcp_tools_button.go index a4a3de78..d62d6009 100644 --- a/uixt/mcp_tools_button.go +++ b/uixt/mcp_tools_button.go @@ -4,10 +4,11 @@ import ( "context" "fmt" - "github.com/httprunner/httprunner/v5/uixt/option" - "github.com/httprunner/httprunner/v5/uixt/types" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" + + "github.com/httprunner/httprunner/v5/uixt/option" + "github.com/httprunner/httprunner/v5/uixt/types" ) // ToolPressButton implements the press_button tool call. @@ -59,7 +60,7 @@ func (t *ToolPressButton) ConvertActionToCallToolRequest(action option.MobileAct arguments := map[string]any{ "button": button, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid press button params: %v", action.Params) } @@ -102,7 +103,7 @@ func (t *ToolHome) Implement() server.ToolHandlerFunc { } func (t *ToolHome) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolBack implements the back tool call. @@ -143,5 +144,5 @@ func (t *ToolBack) Implement() server.ToolHandlerFunc { } func (t *ToolBack) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } diff --git a/uixt/mcp_tools_device.go b/uixt/mcp_tools_device.go index 8a2fa84f..b407f4c5 100644 --- a/uixt/mcp_tools_device.go +++ b/uixt/mcp_tools_device.go @@ -5,11 +5,12 @@ import ( "fmt" "github.com/danielpaulus/go-ios/ios" - "github.com/httprunner/httprunner/v5/pkg/gadb" - "github.com/httprunner/httprunner/v5/uixt/option" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" "github.com/rs/zerolog/log" + + "github.com/httprunner/httprunner/v5/pkg/gadb" + "github.com/httprunner/httprunner/v5/uixt/option" ) // ToolListAvailableDevices implements the list_available_devices tool call. @@ -82,7 +83,7 @@ func (t *ToolListAvailableDevices) Implement() server.ToolHandlerFunc { } func (t *ToolListAvailableDevices) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolSelectDevice implements the select_device tool call. @@ -122,7 +123,7 @@ func (t *ToolSelectDevice) Implement() server.ToolHandlerFunc { } func (t *ToolSelectDevice) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolScreenRecord implements the screenrecord tool call. @@ -212,5 +213,5 @@ func (t *ToolScreenRecord) Implement() server.ToolHandlerFunc { } func (t *ToolScreenRecord) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } diff --git a/uixt/mcp_tools_input.go b/uixt/mcp_tools_input.go index a0be103e..e84da9a9 100644 --- a/uixt/mcp_tools_input.go +++ b/uixt/mcp_tools_input.go @@ -4,9 +4,10 @@ import ( "context" "fmt" - "github.com/httprunner/httprunner/v5/uixt/option" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" + + "github.com/httprunner/httprunner/v5/uixt/option" ) // ToolInput implements the input tool call. @@ -44,8 +45,10 @@ func (t *ToolInput) Implement() server.ToolHandlerFunc { return nil, fmt.Errorf("text is required") } + opts := unifiedReq.Options() + // Input action logic - err = driverExt.Input(unifiedReq.Text) + err = driverExt.Input(unifiedReq.Text, opts...) if err != nil { return NewMCPErrorResponse(fmt.Sprintf("Input failed: %s", err.Error())), err } @@ -62,7 +65,7 @@ func (t *ToolInput) ConvertActionToCallToolRequest(action option.MobileAction) ( arguments := map[string]any{ "text": text, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolSetIme implements the set_ime tool call. @@ -114,7 +117,7 @@ func (t *ToolSetIme) ConvertActionToCallToolRequest(action option.MobileAction) arguments := map[string]any{ "ime": ime, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid set ime params: %v", action.Params) } diff --git a/uixt/mcp_tools_screen.go b/uixt/mcp_tools_screen.go index 9ded9d9a..7a1210d1 100644 --- a/uixt/mcp_tools_screen.go +++ b/uixt/mcp_tools_screen.go @@ -50,7 +50,7 @@ func (t *ToolScreenShot) Implement() server.ToolHandlerFunc { } func (t *ToolScreenShot) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolGetScreenSize implements the get_screen_size tool call. @@ -96,7 +96,7 @@ func (t *ToolGetScreenSize) Implement() server.ToolHandlerFunc { } func (t *ToolGetScreenSize) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } // ToolGetSource implements the get_source tool call. @@ -152,7 +152,7 @@ func (t *ToolGetSource) ConvertActionToCallToolRequest(action option.MobileActio arguments := map[string]any{ "packageName": packageName, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid get source params: %v", action.Params) } diff --git a/uixt/mcp_tools_swipe.go b/uixt/mcp_tools_swipe.go index eaa1a0d6..9b0c1fdf 100644 --- a/uixt/mcp_tools_swipe.go +++ b/uixt/mcp_tools_swipe.go @@ -183,11 +183,7 @@ func (t *ToolSwipeDirection) ConvertActionToCallToolRequest(action option.Mobile if pressDuration := action.ActionOptions.PressDuration; pressDuration > 0 { arguments["pressDuration"] = pressDuration } - - // Extract all action options - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe params: %v", action.Params) } @@ -276,11 +272,7 @@ func (t *ToolSwipeCoordinate) ConvertActionToCallToolRequest(action option.Mobil if pressDuration := action.ActionOptions.PressDuration; pressDuration > 0 { arguments["pressDuration"] = pressDuration } - - // Extract all action options - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe advanced params: %v", action.Params) } @@ -337,11 +329,7 @@ func (t *ToolSwipeToTapApp) ConvertActionToCallToolRequest(action option.MobileA arguments := map[string]any{ "appName": appName, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe to tap app params: %v", action.Params) } @@ -398,11 +386,7 @@ func (t *ToolSwipeToTapText) ConvertActionToCallToolRequest(action option.Mobile arguments := map[string]any{ "text": text, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid swipe to tap text params: %v", action.Params) } @@ -470,11 +454,7 @@ func (t *ToolSwipeToTapTexts) ConvertActionToCallToolRequest(action option.Mobil arguments := map[string]any{ "texts": texts, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolDrag implements the drag tool call. @@ -557,11 +537,7 @@ func (t *ToolDrag) ConvertActionToCallToolRequest(action option.MobileAction) (m if duration := action.ActionOptions.Duration; duration > 0 { arguments["duration"] = duration * 1000 // convert to milliseconds } - - // Extract all action options - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid drag parameters: %v", action.Params) } diff --git a/uixt/mcp_tools_touch.go b/uixt/mcp_tools_touch.go index 539c7bb4..13381b29 100644 --- a/uixt/mcp_tools_touch.go +++ b/uixt/mcp_tools_touch.go @@ -78,11 +78,7 @@ func (t *ToolTapXY) ConvertActionToCallToolRequest(action option.MobileAction) ( if duration := action.ActionOptions.Duration; duration > 0 { arguments["duration"] = duration } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid tap params: %v", action.Params) } @@ -154,11 +150,7 @@ func (t *ToolTapAbsXY) ConvertActionToCallToolRequest(action option.MobileAction if duration := action.ActionOptions.Duration; duration > 0 { arguments["duration"] = duration } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid tap abs params: %v", action.Params) } @@ -220,11 +212,7 @@ func (t *ToolTapByOCR) ConvertActionToCallToolRequest(action option.MobileAction arguments := map[string]any{ "text": text, } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid tap by OCR params: %v", action.Params) } @@ -281,11 +269,7 @@ func (t *ToolTapByCV) ConvertActionToCallToolRequest(action option.MobileAction) arguments := map[string]any{ "imagePath": "", // Will be handled by the tool based on UI types } - - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolDoubleTapXY implements the double_tap_xy tool call. @@ -348,7 +332,7 @@ func (t *ToolDoubleTapXY) ConvertActionToCallToolRequest(action option.MobileAct "x": x, "y": y, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid double tap params: %v", action.Params) } diff --git a/uixt/mcp_tools_utility.go b/uixt/mcp_tools_utility.go index 9246709d..02fa4da6 100644 --- a/uixt/mcp_tools_utility.go +++ b/uixt/mcp_tools_utility.go @@ -94,7 +94,7 @@ func (t *ToolSleep) ConvertActionToCallToolRequest(action option.MobileAction) ( arguments := map[string]any{ "seconds": action.Params, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolSleepMS implements the sleep_ms tool call. @@ -184,7 +184,7 @@ func (t *ToolSleepMS) ConvertActionToCallToolRequest(action option.MobileAction) arguments := map[string]any{ "milliseconds": milliseconds, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolSleepRandom implements the sleep_random tool call. @@ -228,7 +228,7 @@ func (t *ToolSleepRandom) ConvertActionToCallToolRequest(action option.MobileAct arguments := map[string]any{ "params": params, } - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid sleep random params: %v", action.Params) } @@ -271,5 +271,5 @@ func (t *ToolClosePopups) Implement() server.ToolHandlerFunc { } func (t *ToolClosePopups) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) { - return BuildMCPCallToolRequest(t.Name(), map[string]any{}), nil + return BuildMCPCallToolRequest(t.Name(), map[string]any{}, action), nil } diff --git a/uixt/mcp_tools_web.go b/uixt/mcp_tools_web.go index a34c416b..ebcb12e0 100644 --- a/uixt/mcp_tools_web.go +++ b/uixt/mcp_tools_web.go @@ -71,8 +71,7 @@ func (t *ToolWebLoginNoneUI) ConvertActionToCallToolRequest(action option.Mobile arguments["captcha"] = textsSlice[2].(string) arguments["password"] = textsSlice[3].(string) } - - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } // ToolSecondaryClick implements the secondary_click tool call. @@ -134,9 +133,7 @@ func (t *ToolSecondaryClick) ConvertActionToCallToolRequest(action option.Mobile "x": params[0], "y": params[1], } - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid secondary click params: %v", action.Params) } @@ -192,9 +189,7 @@ func (t *ToolHoverBySelector) ConvertActionToCallToolRequest(action option.Mobil arguments := map[string]any{ "selector": selector, } - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid hover by selector params: %v", action.Params) } @@ -250,9 +245,7 @@ func (t *ToolTapBySelector) ConvertActionToCallToolRequest(action option.MobileA arguments := map[string]any{ "selector": selector, } - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid tap by selector params: %v", action.Params) } @@ -308,9 +301,7 @@ func (t *ToolSecondaryClickBySelector) ConvertActionToCallToolRequest(action opt arguments := map[string]any{ "selector": selector, } - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } return mcp.CallToolRequest{}, fmt.Errorf("invalid secondary click by selector params: %v", action.Params) } @@ -384,7 +375,5 @@ func (t *ToolWebCloseTab) ConvertActionToCallToolRequest(action option.MobileAct arguments := map[string]any{ "tabIndex": tabIndex, } - // Extract options to arguments - extractActionOptionsToArguments(action.GetOptions(), arguments) - return BuildMCPCallToolRequest(t.Name(), arguments), nil + return BuildMCPCallToolRequest(t.Name(), arguments, action), nil } From 9d73af4f62e50ca5ff3225e1dd4f24d92c7ccb1e Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 19:29:46 +0800 Subject: [PATCH 2/6] change: remove unused step identifier --- step.go | 1 - step_ui.go | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/step.go b/step.go index c82be894..7e5ec98b 100644 --- a/step.go +++ b/step.go @@ -71,7 +71,6 @@ type ActionResult struct { // one testcase contains one or multiple steps type StepResult struct { Name string `json:"name" yaml:"name"` // step name - Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"` // step identifier StartTime int64 `json:"start_time" yaml:"time"` // step start time in millisecond(ms) StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous Success bool `json:"success" yaml:"success"` // step execution result diff --git a/step_ui.go b/step_ui.go index bc729c48..ea641084 100644 --- a/step_ui.go +++ b/step_ui.go @@ -755,24 +755,6 @@ func runStepMobileUI(s *SessionRunner, step IStep) (stepResult *StepResult, err return stepResult, err } - identifier := mobileStep.Identifier - if mobileStep.Options != nil && identifier == "" { - identifier = mobileStep.Options.Identifier - } - if len(mobileStep.Actions) != 0 && identifier == "" { - for _, action := range mobileStep.Actions { - if action.Identifier != "" { - identifier = action.Identifier - break - } - if action.Options != nil && action.Options.Identifier != "" { - identifier = action.Options.Identifier - break - } - } - } - stepResult.Identifier = identifier - defer func() { attachments := uixt.Attachments{} if err != nil { From 58ce7efb8b1833b2d4752c3b53c1076a59e18ff2 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 21:47:45 +0800 Subject: [PATCH 3/6] change: upgrade eino sdk --- go.mod | 39 ++++---- go.sum | 84 +++++++++-------- mcphost/host.go | 8 +- uixt/ai/env.go | 6 +- uixt/mcp_server.go | 8 +- uixt/mcp_server_test.go | 187 ++++++++++++++++++++------------------ uixt/mcp_tools_ai.go | 17 ++-- uixt/mcp_tools_app.go | 29 +++--- uixt/mcp_tools_button.go | 9 +- uixt/mcp_tools_device.go | 13 +-- uixt/mcp_tools_input.go | 10 +- uixt/mcp_tools_screen.go | 9 +- uixt/mcp_tools_swipe.go | 40 ++++---- uixt/mcp_tools_touch.go | 25 +++-- uixt/mcp_tools_utility.go | 8 +- uixt/mcp_tools_web.go | 30 +++--- uixt/sdk.go | 8 +- 17 files changed, 284 insertions(+), 246 deletions(-) diff --git a/go.mod b/go.mod index 2365d357..b51fc5cb 100644 --- a/go.mod +++ b/go.mod @@ -8,19 +8,19 @@ require ( github.com/Masterminds/semver v1.5.0 github.com/andybalholm/brotli v1.0.4 github.com/antchfx/xmlquery v1.4.4 - github.com/bytedance/sonic v1.13.2 + github.com/bytedance/sonic v1.13.3 github.com/charmbracelet/glamour v0.8.0 github.com/charmbracelet/huh v0.3.0 github.com/charmbracelet/huh/spinner v0.0.0-20250509124401-5fd7cf508477 github.com/charmbracelet/lipgloss v1.1.0 - github.com/cloudwego/eino v0.3.33 - github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250514085234-473e80da5261 - github.com/cloudwego/eino-ext/components/tool/mcp v0.0.0-20250514085234-473e80da5261 - github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250514085234-473e80da5261 + github.com/cloudwego/eino v0.3.47 + github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039 + github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3 + github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8 github.com/danielpaulus/go-ios v1.0.161 github.com/denisbrodbeck/machineid v1.0.1 github.com/fatih/color v1.16.0 - github.com/getkin/kin-openapi v0.121.0 + github.com/getkin/kin-openapi v0.118.0 github.com/getsentry/sentry-go v0.13.0 github.com/gin-gonic/gin v1.10.0 github.com/go-openapi/spec v0.20.7 @@ -32,16 +32,16 @@ require ( github.com/joho/godotenv v1.5.1 github.com/json-iterator/go v1.1.12 github.com/maja42/goval v1.2.1 - github.com/mark3labs/mcp-go v0.27.1 + github.com/mark3labs/mcp-go v0.32.0 github.com/mitchellh/mapstructure v1.5.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 - golang.org/x/net v0.40.0 + golang.org/x/net v0.41.0 golang.org/x/term v0.32.0 - golang.org/x/text v0.25.0 + golang.org/x/text v0.26.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -68,6 +68,7 @@ require ( github.com/dlclark/regexp2 v1.11.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect + github.com/evanphx/json-patch v0.5.2 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -91,10 +92,10 @@ require ( github.com/hashicorp/go-plugin v1.4.10 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/yaml v0.2.0 // indirect + github.com/invopop/yaml v0.3.1 // indirect github.com/jhump/protoreflect v1.8.2 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect @@ -102,7 +103,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6 // indirect + github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/miekg/dns v1.1.57 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -128,7 +129,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect - github.com/spf13/cast v1.8.0 // indirect + github.com/spf13/cast v1.9.2 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -140,14 +141,14 @@ require ( github.com/yuin/goldmark-emoji v1.0.3 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/arch v0.17.0 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.14.0 // indirect + golang.org/x/arch v0.18.0 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/sync v0.15.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.33.0 // indirect + golang.org/x/tools v0.34.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect google.golang.org/grpc v1.71.0 // indirect diff --git a/go.sum b/go.sum index 8d381d89..f69d5ecf 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqR github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8= github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= @@ -70,14 +70,14 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/eino v0.3.33 h1:C7BXUiLfyVDt0u+77B9X47nJ2OqzPPJ4kzTjRy+QuQ8= -github.com/cloudwego/eino v0.3.33/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250514085234-473e80da5261 h1:XNlnz2o8NC9eNv97nuVI4Zs9b+8XzvKRFgXTTZvVNW8= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250514085234-473e80da5261/go.mod h1:uXIWTFbaAbZ1128EIXjFc4S+tDqmz1idMZd5qt5kkwU= -github.com/cloudwego/eino-ext/components/tool/mcp v0.0.0-20250514085234-473e80da5261 h1:bjNUIUzuqDOm6Z+HmP+2Xl33BKr/cti7w+DPklAujrs= -github.com/cloudwego/eino-ext/components/tool/mcp v0.0.0-20250514085234-473e80da5261/go.mod h1:flYqhc4z9zZ1MxWnMCVVwKrNEWQNbuapq3NCwwX/xLs= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250514085234-473e80da5261 h1:qyvq38EscdgmFqcPso3kolmL7jDM12uquA11hQ2D+X4= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250514085234-473e80da5261/go.mod h1:21bzzKhB1SSBr2jUaEBvNs75ZxSWSfIyM3oF2RB1ELs= +github.com/cloudwego/eino v0.3.47 h1:nl1Q1QZhFAyl169M32KZB8vj1Zp6fqeSjVF1lVzUSsw= +github.com/cloudwego/eino v0.3.47/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039 h1:Lc074nJ801sh3Gg6FH8qJsBh0ZNQw6+kJRnYDikgK6c= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039/go.mod h1:2mFQQnlhJrNgbW6YX1MOUUfXkGSbTz9Ylx37fbR0xBo= +github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3 h1:kT8yynQh8q92BPofkHxxnXslJUj5AKex5+NpMrd+BU4= +github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3/go.mod h1:D1Yircehgx7em8EH6vw8If+ATjtXl60IpBzVaqFBx3c= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8 h1:WM3r11XwY39Ua8cH/LhGNr6vrzS73XEGxrAejN+C1dQ= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8/go.mod h1:iB0W8l+OqKNL5LtJQ9JaGYXekhsxVxrDMfnfD9L+5gc= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= @@ -101,6 +101,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -109,8 +111,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/getkin/kin-openapi v0.121.0 h1:KbQmTugy+lQF+ed5H3tikjT4prqx5+KCLAq4U81Hkcw= -github.com/getkin/kin-openapi v0.121.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= +github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= +github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= @@ -193,6 +195,7 @@ github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfre github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE= @@ -211,8 +214,9 @@ github.com/httprunner/funplugin v0.5.5/go.mod h1:YZzBBSOSdLZEpHZz0P2E5SOQ+o1+Fbn github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.8.2 h1:k2xE7wcUomeqwY0LDCYA16y4WWfyTcMx5mKhk0d4ua0= github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= @@ -233,8 +237,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -251,12 +255,13 @@ github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/maja42/goval v1.2.1 h1:fyEgzddqPgCZsKcFLk4C6SdCHyEaAHYvtZG4mGzQOHU= github.com/maja42/goval v1.2.1/go.mod h1:42LU+BQXL/veE9jnTTUOSj38GRmOTSThYSXRVodI5J4= -github.com/mark3labs/mcp-go v0.27.1 h1:0aPKgy5tLMALToWmEKUWcv+91gOnt6uYEkQcbmB2o+Q= -github.com/mark3labs/mcp-go v0.27.1/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= +github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8= +github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -272,8 +277,8 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6 h1:nmdXxiUX48DZ2ELC/jSYzyGUVgxVEF2QJRGhLJ933zA= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6/go.mod h1:kyz7fcXqXtccmRAIARn1Q+cKLNXJHC3AoqqJGeCqNI0= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde h1:pq2I0uxUR4lfr4OmqvE8QdHj9UML9b1jZu8L3dI2eu8= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde/go.mod h1:CqSFsV6AkkL2fixd25WYjRAolns+gQrY1x/Cz9c30v8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= @@ -315,6 +320,7 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= @@ -357,8 +363,8 @@ github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sS github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= -github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= -github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= +github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -383,6 +389,8 @@ github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9 h1:aeN+ghOV0b2VC github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9/go.mod h1:roo6cZ/uqpwKMuvPG0YmzI5+AmUiMWfjCBZpGXqbTxE= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= @@ -417,8 +425,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU= -golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -430,11 +438,11 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -447,8 +455,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -469,8 +477,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -483,8 +491,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -536,8 +544,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -554,8 +562,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/mcphost/host.go b/mcphost/host.go index c9e65cab..4dba8785 100644 --- a/mcphost/host.go +++ b/mcphost/host.go @@ -340,13 +340,7 @@ func (h *MCPHost) InvokeTool(ctx context.Context, } req := mcp.CallToolRequest{ - Params: struct { - Name string `json:"name"` - Arguments map[string]any `json:"arguments,omitempty"` - Meta *struct { - ProgressToken mcp.ProgressToken `json:"progressToken,omitempty"` - } `json:"_meta,omitempty"` - }{ + Params: mcp.CallToolParams{ Name: mcpTool.Name, Arguments: arguments, }, diff --git a/uixt/ai/env.go b/uixt/ai/env.go index a6b0d996..6018660d 100644 --- a/uixt/ai/env.go +++ b/uixt/ai/env.go @@ -6,11 +6,12 @@ import ( "time" "github.com/cloudwego/eino-ext/components/model/openai" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/internal/config" "github.com/httprunner/httprunner/v5/uixt/option" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" ) // LLM model config env variables @@ -80,6 +81,7 @@ func getServiceEnvPrefix(modelType option.LLMServiceType) string { // It first tries to get service-specific config, then falls back to default config // Model name is derived from the service type, no need for separate MODEL_NAME env var func getModelConfigFromEnv(modelType option.LLMServiceType) (baseURL, apiKey, modelName string, err error) { + log.Info().Str("modelType", string(modelType)).Msg("getModelConfigFromEnv") servicePrefix := getServiceEnvPrefix(modelType) // Try to get service-specific configuration first diff --git a/uixt/mcp_server.go b/uixt/mcp_server.go index 087b9f4c..346ede50 100644 --- a/uixt/mcp_server.go +++ b/uixt/mcp_server.go @@ -163,13 +163,7 @@ func BuildMCPCallToolRequest(toolName option.ActionName, arguments map[string]an extractActionOptionsToArguments(action.GetOptions(), arguments) return mcp.CallToolRequest{ - Params: struct { - Name string `json:"name"` - Arguments map[string]any `json:"arguments,omitempty"` - Meta *struct { - ProgressToken mcp.ProgressToken `json:"progressToken,omitempty"` - } `json:"_meta,omitempty"` - }{ + Params: mcp.CallToolParams{ Name: string(toolName), Arguments: arguments, }, diff --git a/uixt/mcp_server_test.go b/uixt/mcp_server_test.go index a8074108..ba102556 100644 --- a/uixt/mcp_server_test.go +++ b/uixt/mcp_server_test.go @@ -3,10 +3,11 @@ package uixt import ( "testing" - "github.com/httprunner/httprunner/v5/internal/json" - "github.com/httprunner/httprunner/v5/uixt/option" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/httprunner/httprunner/v5/internal/json" + "github.com/httprunner/httprunner/v5/uixt/option" ) func TestNewMCPServer(t *testing.T) { @@ -154,7 +155,7 @@ func TestIgnoreNotFoundErrorOption(t *testing.T) { assert.NoError(t, err, "Should convert action to request without error") // Verify that ignore_NotFoundError option is included in arguments - args := request.Params.Arguments + args := request.GetArguments() assert.Equal(t, true, args["ignore_NotFoundError"], "ignore_NotFoundError should be true") assert.Equal(t, 2, args["max_retry_times"], "max_retry_times should be 2") assert.Equal(t, 1, args["index"], "index should be 1") @@ -211,7 +212,7 @@ func TestToolListAvailableDevices(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_ListAvailableDevices), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolSelectDevice tests the ToolSelectDevice implementation @@ -264,9 +265,10 @@ func TestToolTapXY(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_TapXY), request.Params.Name) - assert.Equal(t, 0.5, request.Params.Arguments["x"]) - assert.Equal(t, 0.6, request.Params.Arguments["y"]) - assert.Equal(t, 1.5, request.Params.Arguments["duration"]) + args := request.GetArguments() + assert.Equal(t, 0.5, args["x"]) + assert.Equal(t, 0.6, args["y"]) + assert.Equal(t, 1.5, args["duration"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -302,9 +304,10 @@ func TestToolTapAbsXY(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_TapAbsXY), request.Params.Name) - assert.Equal(t, 100.0, request.Params.Arguments["x"]) - assert.Equal(t, 200.0, request.Params.Arguments["y"]) - assert.Equal(t, 2.0, request.Params.Arguments["duration"]) + args := request.GetArguments() + assert.Equal(t, 100.0, args["x"]) + assert.Equal(t, 200.0, args["y"]) + assert.Equal(t, 2.0, args["duration"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -345,12 +348,13 @@ func TestToolTapByOCR(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_TapByOCR), request.Params.Name) - assert.Equal(t, "test_text", request.Params.Arguments["text"]) - assert.Equal(t, true, request.Params.Arguments["ignore_NotFoundError"]) - assert.Equal(t, 3, request.Params.Arguments["max_retry_times"]) - assert.Equal(t, 1, request.Params.Arguments["index"]) - assert.Equal(t, true, request.Params.Arguments["regex"]) - assert.Equal(t, true, request.Params.Arguments["tap_random_rect"]) + args := request.GetArguments() + assert.Equal(t, "test_text", args["text"]) + assert.Equal(t, true, args["ignore_NotFoundError"]) + assert.Equal(t, 3, args["max_retry_times"]) + assert.Equal(t, 1, args["index"]) + assert.Equal(t, true, args["regex"]) + assert.Equal(t, true, args["tap_random_rect"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -389,10 +393,11 @@ func TestToolTapByCV(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_TapByCV), request.Params.Name) - assert.Equal(t, "", request.Params.Arguments["imagePath"]) - assert.Equal(t, true, request.Params.Arguments["ignore_NotFoundError"]) - assert.Equal(t, 2, request.Params.Arguments["max_retry_times"]) - assert.Equal(t, true, request.Params.Arguments["tap_random_rect"]) + args := request.GetArguments() + assert.Equal(t, "", args["imagePath"]) + assert.Equal(t, true, args["ignore_NotFoundError"]) + assert.Equal(t, 2, args["max_retry_times"]) + assert.Equal(t, true, args["tap_random_rect"]) } // TestToolDoubleTapXY tests the ToolDoubleTapXY implementation @@ -417,8 +422,9 @@ func TestToolDoubleTapXY(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_DoubleTapXY), request.Params.Name) - assert.Equal(t, 0.3, request.Params.Arguments["x"]) - assert.Equal(t, 0.7, request.Params.Arguments["y"]) + args := request.GetArguments() + assert.Equal(t, 0.3, args["x"]) + assert.Equal(t, 0.7, args["y"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -455,9 +461,10 @@ func TestToolSwipe(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(directionAction) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Swipe), request.Params.Name) - assert.Equal(t, "up", request.Params.Arguments["direction"]) - assert.Equal(t, 1.5, request.Params.Arguments["duration"]) - assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"]) + args := request.GetArguments() + assert.Equal(t, "up", args["direction"]) + assert.Equal(t, 1.5, args["duration"]) + assert.Equal(t, 0.5, args["pressDuration"]) // Test ConvertActionToCallToolRequest with coordinate params coordinateAction := option.MobileAction{ @@ -471,12 +478,13 @@ func TestToolSwipe(t *testing.T) { request, err = tool.ConvertActionToCallToolRequest(coordinateAction) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Swipe), request.Params.Name) - assert.Equal(t, 0.1, request.Params.Arguments["from_x"]) - assert.Equal(t, 0.2, request.Params.Arguments["from_y"]) - assert.Equal(t, 0.8, request.Params.Arguments["to_x"]) - assert.Equal(t, 0.9, request.Params.Arguments["to_y"]) - assert.Equal(t, 2.0, request.Params.Arguments["duration"]) - assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"]) + args = request.GetArguments() + assert.Equal(t, 0.1, args["from_x"]) + assert.Equal(t, 0.2, args["from_y"]) + assert.Equal(t, 0.8, args["to_x"]) + assert.Equal(t, 0.9, args["to_y"]) + assert.Equal(t, 2.0, args["duration"]) + assert.Equal(t, 1.0, args["pressDuration"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -521,9 +529,10 @@ func TestToolSwipeDirection(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SwipeDirection), request.Params.Name) - assert.Equal(t, "up", request.Params.Arguments["direction"]) - assert.Equal(t, 1.0, request.Params.Arguments["duration"]) - assert.Equal(t, 0.5, request.Params.Arguments["pressDuration"]) + args := request.GetArguments() + assert.Equal(t, "up", args["direction"]) + assert.Equal(t, 1.0, args["duration"]) + assert.Equal(t, 0.5, args["pressDuration"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -560,12 +569,13 @@ func TestToolSwipeCoordinate(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SwipeCoordinate), request.Params.Name) - assert.Equal(t, 0.1, request.Params.Arguments["from_x"]) - assert.Equal(t, 0.2, request.Params.Arguments["from_y"]) - assert.Equal(t, 0.8, request.Params.Arguments["to_x"]) - assert.Equal(t, 0.9, request.Params.Arguments["to_y"]) - assert.Equal(t, 2.0, request.Params.Arguments["duration"]) - assert.Equal(t, 1.0, request.Params.Arguments["pressDuration"]) + args := request.GetArguments() + assert.Equal(t, 0.1, args["from_x"]) + assert.Equal(t, 0.2, args["from_y"]) + assert.Equal(t, 0.8, args["to_x"]) + assert.Equal(t, 0.9, args["to_y"]) + assert.Equal(t, 2.0, args["duration"]) + assert.Equal(t, 1.0, args["pressDuration"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -604,10 +614,11 @@ func TestToolSwipeToTapApp(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SwipeToTapApp), request.Params.Name) - assert.Equal(t, "WeChat", request.Params.Arguments["appName"]) - assert.Equal(t, true, request.Params.Arguments["ignore_NotFoundError"]) - assert.Equal(t, 3, request.Params.Arguments["max_retry_times"]) - assert.Equal(t, 1, request.Params.Arguments["index"]) + args := request.GetArguments() + assert.Equal(t, "WeChat", args["appName"]) + assert.Equal(t, true, args["ignore_NotFoundError"]) + assert.Equal(t, 3, args["max_retry_times"]) + assert.Equal(t, 1, args["index"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -646,10 +657,11 @@ func TestToolSwipeToTapText(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SwipeToTapText), request.Params.Name) - assert.Equal(t, "Submit", request.Params.Arguments["text"]) - assert.Equal(t, true, request.Params.Arguments["ignore_NotFoundError"]) - assert.Equal(t, 2, request.Params.Arguments["max_retry_times"]) - assert.Equal(t, true, request.Params.Arguments["regex"]) + args := request.GetArguments() + assert.Equal(t, "Submit", args["text"]) + assert.Equal(t, true, args["ignore_NotFoundError"]) + assert.Equal(t, 2, args["max_retry_times"]) + assert.Equal(t, true, args["regex"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -688,11 +700,12 @@ func TestToolSwipeToTapTexts(t *testing.T) { assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SwipeToTapTexts), request.Params.Name) - texts, ok := request.Params.Arguments["texts"].([]string) + args := request.GetArguments() + texts, ok := args["texts"].([]string) require.True(t, ok) assert.Equal(t, []string{"OK", "确定", "Submit"}, texts) - assert.Equal(t, true, request.Params.Arguments["ignore_NotFoundError"]) - assert.Equal(t, true, request.Params.Arguments["regex"]) + assert.Equal(t, true, args["ignore_NotFoundError"]) + assert.Equal(t, true, args["regex"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -728,11 +741,12 @@ func TestToolDrag(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Drag), request.Params.Name) - assert.Equal(t, 0.1, request.Params.Arguments["from_x"]) - assert.Equal(t, 0.2, request.Params.Arguments["from_y"]) - assert.Equal(t, 0.8, request.Params.Arguments["to_x"]) - assert.Equal(t, 0.9, request.Params.Arguments["to_y"]) - assert.Equal(t, 2500.0, request.Params.Arguments["duration"]) // converted to milliseconds + args := request.GetArguments() + assert.Equal(t, 0.1, args["from_x"]) + assert.Equal(t, 0.2, args["from_y"]) + assert.Equal(t, 0.8, args["to_x"]) + assert.Equal(t, 0.9, args["to_y"]) + assert.Equal(t, 2500.0, args["duration"]) // converted to milliseconds // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -765,7 +779,7 @@ func TestToolInput(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Input), request.Params.Name) - assert.Equal(t, "Hello World", request.Params.Arguments["text"]) + assert.Equal(t, "Hello World", request.GetArguments()["text"]) } // TestToolScreenShot tests the ToolScreenShot implementation @@ -790,7 +804,7 @@ func TestToolScreenShot(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_ScreenShot), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolGetScreenSize tests the ToolGetScreenSize implementation @@ -815,7 +829,7 @@ func TestToolGetScreenSize(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_GetScreenSize), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolPressButton tests the ToolPressButton implementation @@ -840,7 +854,7 @@ func TestToolPressButton(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_PressButton), request.Params.Name) - assert.Equal(t, "HOME", request.Params.Arguments["button"]) + assert.Equal(t, "HOME", request.GetArguments()["button"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -873,7 +887,7 @@ func TestToolHome(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Home), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolBack tests the ToolBack implementation @@ -898,7 +912,7 @@ func TestToolBack(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Back), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolListPackages tests the ToolListPackages implementation @@ -923,7 +937,7 @@ func TestToolListPackages(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_ListPackages), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolLaunchApp tests the ToolLaunchApp implementation @@ -948,7 +962,7 @@ func TestToolLaunchApp(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AppLaunch), request.Params.Name) - assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"]) + assert.Equal(t, "com.example.app", request.GetArguments()["packageName"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -981,7 +995,7 @@ func TestToolTerminateApp(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AppTerminate), request.Params.Name) - assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"]) + assert.Equal(t, "com.example.app", request.GetArguments()["packageName"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1014,7 +1028,7 @@ func TestToolAppInstall(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AppInstall), request.Params.Name) - assert.Equal(t, "https://example.com/app.apk", request.Params.Arguments["appUrl"]) + assert.Equal(t, "https://example.com/app.apk", request.GetArguments()["appUrl"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1047,7 +1061,7 @@ func TestToolAppUninstall(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AppUninstall), request.Params.Name) - assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"]) + assert.Equal(t, "com.example.app", request.GetArguments()["packageName"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1080,7 +1094,7 @@ func TestToolAppClear(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AppClear), request.Params.Name) - assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"]) + assert.Equal(t, "com.example.app", request.GetArguments()["packageName"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1113,7 +1127,7 @@ func TestToolSleep(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Sleep), request.Params.Name) - assert.Equal(t, 2.5, request.Params.Arguments["seconds"]) + assert.Equal(t, 2.5, request.GetArguments()["seconds"]) } // TestToolSleepMS tests the ToolSleepMS implementation @@ -1138,7 +1152,7 @@ func TestToolSleepMS(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SleepMS), request.Params.Name) - assert.Equal(t, int64(1500), request.Params.Arguments["milliseconds"]) + assert.Equal(t, int64(1500), request.GetArguments()["milliseconds"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1172,7 +1186,7 @@ func TestToolSleepRandom(t *testing.T) { assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SleepRandom), request.Params.Name) - params, ok := request.Params.Arguments["params"].([]float64) + params, ok := request.GetArguments()["params"].([]float64) require.True(t, ok) assert.Equal(t, []float64{1.0, 3.0}, params) @@ -1207,7 +1221,7 @@ func TestToolSetIme(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SetIme), request.Params.Name) - assert.Equal(t, "com.google.android.inputmethod.latin", request.Params.Arguments["ime"]) + assert.Equal(t, "com.google.android.inputmethod.latin", request.GetArguments()["ime"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1240,7 +1254,7 @@ func TestToolGetSource(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_GetSource), request.Params.Name) - assert.Equal(t, "com.example.app", request.Params.Arguments["packageName"]) + assert.Equal(t, "com.example.app", request.GetArguments()["packageName"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1273,7 +1287,7 @@ func TestToolClosePopups(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_ClosePopups), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolAIAction tests the ToolAIAction implementation @@ -1298,7 +1312,7 @@ func TestToolAIAction(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_AIAction), request.Params.Name) - assert.Equal(t, "Click on the login button", request.Params.Arguments["prompt"]) + assert.Equal(t, "Click on the login button", request.GetArguments()["prompt"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1331,7 +1345,7 @@ func TestToolAIQuery(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Query), request.Params.Name) - assert.Equal(t, "What is displayed on the screen?", request.Params.Arguments["prompt"]) + assert.Equal(t, "What is displayed on the screen?", request.GetArguments()["prompt"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1364,7 +1378,7 @@ func TestToolFinished(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_Finished), request.Params.Name) - assert.Equal(t, "Task completed successfully", request.Params.Arguments["content"]) + assert.Equal(t, "Task completed successfully", request.GetArguments()["content"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1397,7 +1411,7 @@ func TestToolWebLoginNoneUI(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_WebLoginNoneUI), request.Params.Name) - assert.Empty(t, request.Params.Arguments) + assert.Empty(t, request.GetArguments()) } // TestToolSecondaryClick tests the ToolSecondaryClick implementation @@ -1422,8 +1436,9 @@ func TestToolSecondaryClick(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SecondaryClick), request.Params.Name) - assert.Equal(t, 0.5, request.Params.Arguments["x"]) - assert.Equal(t, 0.6, request.Params.Arguments["y"]) + args := request.GetArguments() + assert.Equal(t, 0.5, args["x"]) + assert.Equal(t, 0.6, args["y"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1456,7 +1471,7 @@ func TestToolHoverBySelector(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_HoverBySelector), request.Params.Name) - assert.Equal(t, "#login-button", request.Params.Arguments["selector"]) + assert.Equal(t, "#login-button", request.GetArguments()["selector"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1489,7 +1504,7 @@ func TestToolTapBySelector(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_TapBySelector), request.Params.Name) - assert.Equal(t, "//button[@id='submit']", request.Params.Arguments["selector"]) + assert.Equal(t, "//button[@id='submit']", request.GetArguments()["selector"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1522,7 +1537,7 @@ func TestToolSecondaryClickBySelector(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_SecondaryClickBySelector), request.Params.Name) - assert.Equal(t, ".context-menu-trigger", request.Params.Arguments["selector"]) + assert.Equal(t, ".context-menu-trigger", request.GetArguments()["selector"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1555,7 +1570,7 @@ func TestToolWebCloseTab(t *testing.T) { request, err := tool.ConvertActionToCallToolRequest(action) assert.NoError(t, err) assert.Equal(t, string(option.ACTION_WebCloseTab), request.Params.Name) - assert.Equal(t, 1, request.Params.Arguments["tabIndex"]) + assert.Equal(t, 1, request.GetArguments()["tabIndex"]) // Test ConvertActionToCallToolRequest with invalid params invalidAction := option.MobileAction{ @@ -1583,7 +1598,7 @@ func TestPreMarkOperationConfiguration(t *testing.T) { request, err := tapTool.ConvertActionToCallToolRequest(actionWithPreMark) assert.NoError(t, err) - assert.Equal(t, true, request.Params.Arguments["pre_mark_operation"]) + assert.Equal(t, true, request.GetArguments()["pre_mark_operation"]) // Test conversion without pre_mark_operation actionWithoutPreMark := option.MobileAction{ @@ -1595,7 +1610,7 @@ func TestPreMarkOperationConfiguration(t *testing.T) { request2, err := tapTool.ConvertActionToCallToolRequest(actionWithoutPreMark) assert.NoError(t, err) // Should not have pre_mark_operation in arguments when false - _, exists := request2.Params.Arguments["pre_mark_operation"] + _, exists := request2.GetArguments()["pre_mark_operation"] assert.False(t, exists) } diff --git a/uixt/mcp_tools_ai.go b/uixt/mcp_tools_ai.go index d969f67a..7fe29f38 100644 --- a/uixt/mcp_tools_ai.go +++ b/uixt/mcp_tools_ai.go @@ -32,12 +32,13 @@ func (t *ToolStartToGoal) Options() []mcp.ToolOption { func (t *ToolStartToGoal) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -88,12 +89,13 @@ func (t *ToolAIAction) Options() []mcp.ToolOption { func (t *ToolAIAction) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -145,12 +147,13 @@ func (t *ToolAIQuery) Options() []mcp.ToolOption { func (t *ToolAIQuery) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -205,7 +208,7 @@ func (t *ToolFinished) Options() []mcp.ToolOption { func (t *ToolFinished) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(request.GetArguments()) if err != nil { return nil, err } diff --git a/uixt/mcp_tools_app.go b/uixt/mcp_tools_app.go index 6afe3f19..1ad61843 100644 --- a/uixt/mcp_tools_app.go +++ b/uixt/mcp_tools_app.go @@ -33,7 +33,7 @@ func (t *ToolListPackages) Options() []mcp.ToolOption { func (t *ToolListPackages) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, err } @@ -78,12 +78,13 @@ func (t *ToolLaunchApp) Options() []mcp.ToolOption { func (t *ToolLaunchApp) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -137,12 +138,13 @@ func (t *ToolTerminateApp) Options() []mcp.ToolOption { func (t *ToolTerminateApp) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -201,12 +203,13 @@ func (t *ToolAppInstall) Options() []mcp.ToolOption { func (t *ToolAppInstall) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -255,12 +258,13 @@ func (t *ToolAppUninstall) Options() []mcp.ToolOption { func (t *ToolAppUninstall) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -309,12 +313,13 @@ func (t *ToolAppClear) Options() []mcp.ToolOption { func (t *ToolAppClear) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -364,7 +369,7 @@ func (t *ToolGetForegroundApp) Options() []mcp.ToolOption { func (t *ToolGetForegroundApp) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } diff --git a/uixt/mcp_tools_button.go b/uixt/mcp_tools_button.go index d62d6009..f84f48e1 100644 --- a/uixt/mcp_tools_button.go +++ b/uixt/mcp_tools_button.go @@ -32,12 +32,13 @@ func (t *ToolPressButton) Options() []mcp.ToolOption { func (t *ToolPressButton) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -84,7 +85,7 @@ func (t *ToolHome) Options() []mcp.ToolOption { func (t *ToolHome) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } @@ -125,7 +126,7 @@ func (t *ToolBack) Options() []mcp.ToolOption { func (t *ToolBack) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } diff --git a/uixt/mcp_tools_device.go b/uixt/mcp_tools_device.go index b407f4c5..e09dd906 100644 --- a/uixt/mcp_tools_device.go +++ b/uixt/mcp_tools_device.go @@ -109,7 +109,7 @@ func (t *ToolSelectDevice) Options() []mcp.ToolOption { func (t *ToolSelectDevice) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, err } @@ -155,7 +155,8 @@ func (t *ToolScreenRecord) Options() []mcp.ToolOption { func (t *ToolScreenRecord) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, err } @@ -163,19 +164,19 @@ func (t *ToolScreenRecord) Implement() server.ToolHandlerFunc { // Parse options from arguments var opts []option.ActionOption - if duration, ok := request.Params.Arguments["duration"].(float64); ok && duration > 0 { + if duration, ok := arguments["duration"].(float64); ok && duration > 0 { opts = append(opts, option.WithDuration(duration)) } - if path, ok := request.Params.Arguments["screenRecordPath"].(string); ok && path != "" { + if path, ok := arguments["screenRecordPath"].(string); ok && path != "" { opts = append(opts, option.WithScreenRecordPath(path)) } - if audio, ok := request.Params.Arguments["screenRecordWithAudio"].(bool); ok && audio { + if audio, ok := arguments["screenRecordWithAudio"].(bool); ok && audio { opts = append(opts, option.WithScreenRecordAudio(true)) } - if scrcpy, ok := request.Params.Arguments["screenRecordWithScrcpy"].(bool); ok && scrcpy { + if scrcpy, ok := arguments["screenRecordWithScrcpy"].(bool); ok && scrcpy { opts = append(opts, option.WithScreenRecordScrcpy(true)) } diff --git a/uixt/mcp_tools_input.go b/uixt/mcp_tools_input.go index e84da9a9..764b8f4a 100644 --- a/uixt/mcp_tools_input.go +++ b/uixt/mcp_tools_input.go @@ -31,12 +31,13 @@ func (t *ToolInput) Options() []mcp.ToolOption { func (t *ToolInput) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -89,12 +90,13 @@ func (t *ToolSetIme) Options() []mcp.ToolOption { func (t *ToolSetIme) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } diff --git a/uixt/mcp_tools_screen.go b/uixt/mcp_tools_screen.go index 7a1210d1..33eb2cd0 100644 --- a/uixt/mcp_tools_screen.go +++ b/uixt/mcp_tools_screen.go @@ -31,7 +31,7 @@ func (t *ToolScreenShot) Options() []mcp.ToolOption { func (t *ToolScreenShot) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, err } @@ -75,7 +75,7 @@ func (t *ToolGetScreenSize) Options() []mcp.ToolOption { func (t *ToolGetScreenSize) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } @@ -121,12 +121,13 @@ func (t *ToolGetSource) Options() []mcp.ToolOption { func (t *ToolGetSource) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } diff --git a/uixt/mcp_tools_swipe.go b/uixt/mcp_tools_swipe.go index 9b0c1fdf..3cbc774b 100644 --- a/uixt/mcp_tools_swipe.go +++ b/uixt/mcp_tools_swipe.go @@ -37,7 +37,7 @@ func (t *ToolSwipe) Options() []mcp.ToolOption { func (t *ToolSwipe) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { // Check if it's direction-based swipe (has "direction" parameter) - if _, exists := request.Params.Arguments["direction"]; exists { + if _, exists := request.GetArguments()["direction"]; exists { // Delegate to ToolSwipeDirection directionTool := &ToolSwipeDirection{} return directionTool.Implement()(ctx, request) @@ -104,12 +104,13 @@ func (t *ToolSwipeDirection) Options() []mcp.ToolOption { func (t *ToolSwipeDirection) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -212,12 +213,13 @@ func (t *ToolSwipeCoordinate) Options() []mcp.ToolOption { func (t *ToolSwipeCoordinate) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -298,12 +300,13 @@ func (t *ToolSwipeToTapApp) Options() []mcp.ToolOption { func (t *ToolSwipeToTapApp) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -355,12 +358,13 @@ func (t *ToolSwipeToTapText) Options() []mcp.ToolOption { func (t *ToolSwipeToTapText) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -413,12 +417,13 @@ func (t *ToolSwipeToTapTexts) Options() []mcp.ToolOption { func (t *ToolSwipeToTapTexts) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -481,21 +486,22 @@ func (t *ToolDrag) Options() []mcp.ToolOption { func (t *ToolDrag) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } // Validate required parameters - check if coordinates are provided (not just non-zero) - _, hasFromX := request.Params.Arguments["from_x"] - _, hasFromY := request.Params.Arguments["from_y"] - _, hasToX := request.Params.Arguments["to_x"] - _, hasToY := request.Params.Arguments["to_y"] + _, hasFromX := arguments["from_x"] + _, hasFromY := arguments["from_y"] + _, hasToX := arguments["to_x"] + _, hasToY := arguments["to_y"] if !hasFromX || !hasFromY || !hasToX || !hasToY { return nil, fmt.Errorf("from_x, from_y, to_x, and to_y coordinates are required") } diff --git a/uixt/mcp_tools_touch.go b/uixt/mcp_tools_touch.go index 13381b29..f78d7ef1 100644 --- a/uixt/mcp_tools_touch.go +++ b/uixt/mcp_tools_touch.go @@ -33,12 +33,13 @@ func (t *ToolTapXY) Options() []mcp.ToolOption { func (t *ToolTapXY) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -105,12 +106,13 @@ func (t *ToolTapAbsXY) Options() []mcp.ToolOption { func (t *ToolTapAbsXY) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -176,12 +178,13 @@ func (t *ToolTapByOCR) Options() []mcp.ToolOption { func (t *ToolTapByOCR) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -236,12 +239,13 @@ func (t *ToolTapByCV) Options() []mcp.ToolOption { func (t *ToolTapByCV) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -294,12 +298,13 @@ func (t *ToolDoubleTapXY) Options() []mcp.ToolOption { func (t *ToolDoubleTapXY) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } diff --git a/uixt/mcp_tools_utility.go b/uixt/mcp_tools_utility.go index 02fa4da6..e95a6907 100644 --- a/uixt/mcp_tools_utility.go +++ b/uixt/mcp_tools_utility.go @@ -38,7 +38,7 @@ func (t *ToolSleep) Options() []mcp.ToolOption { func (t *ToolSleep) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - seconds, ok := request.Params.Arguments["seconds"] + seconds, ok := request.GetArguments()["seconds"] if !ok { log.Warn().Msg("seconds parameter is required, using default value 5.0 seconds") seconds = 5.0 @@ -120,7 +120,7 @@ func (t *ToolSleepMS) Options() []mcp.ToolOption { func (t *ToolSleepMS) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - milliseconds, ok := request.Params.Arguments["milliseconds"] + milliseconds, ok := request.GetArguments()["milliseconds"] if !ok { log.Warn().Msg("milliseconds parameter is required, using default value 1000 milliseconds") milliseconds = 1000 @@ -208,7 +208,7 @@ func (t *ToolSleepRandom) Options() []mcp.ToolOption { func (t *ToolSleepRandom) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(request.GetArguments()) if err != nil { return nil, err } @@ -252,7 +252,7 @@ func (t *ToolClosePopups) Options() []mcp.ToolOption { func (t *ToolClosePopups) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + driverExt, err := setupXTDriver(ctx, request.GetArguments()) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } diff --git a/uixt/mcp_tools_web.go b/uixt/mcp_tools_web.go index ebcb12e0..4de20a56 100644 --- a/uixt/mcp_tools_web.go +++ b/uixt/mcp_tools_web.go @@ -34,12 +34,13 @@ func (t *ToolWebLoginNoneUI) Options() []mcp.ToolOption { func (t *ToolWebLoginNoneUI) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -96,12 +97,13 @@ func (t *ToolSecondaryClick) Options() []mcp.ToolOption { func (t *ToolSecondaryClick) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -159,12 +161,13 @@ func (t *ToolHoverBySelector) Options() []mcp.ToolOption { func (t *ToolHoverBySelector) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -215,12 +218,13 @@ func (t *ToolTapBySelector) Options() []mcp.ToolOption { func (t *ToolTapBySelector) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -271,12 +275,13 @@ func (t *ToolSecondaryClickBySelector) Options() []mcp.ToolOption { func (t *ToolSecondaryClickBySelector) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } @@ -327,12 +332,13 @@ func (t *ToolWebCloseTab) Options() []mcp.ToolOption { func (t *ToolWebCloseTab) Implement() server.ToolHandlerFunc { return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - driverExt, err := setupXTDriver(ctx, request.Params.Arguments) + arguments := request.GetArguments() + driverExt, err := setupXTDriver(ctx, arguments) if err != nil { return nil, fmt.Errorf("setup driver failed: %w", err) } - unifiedReq, err := parseActionOptions(request.Params.Arguments) + unifiedReq, err := parseActionOptions(arguments) if err != nil { return nil, err } diff --git a/uixt/sdk.go b/uixt/sdk.go index d315bbca..8ea1c609 100644 --- a/uixt/sdk.go +++ b/uixt/sdk.go @@ -230,13 +230,7 @@ func (dExt *XTDriver) CallMCPTool(ctx context.Context, // Call MCP tool req := mcp.CallToolRequest{ - Params: struct { - Name string `json:"name"` - Arguments map[string]any `json:"arguments,omitempty"` - Meta *struct { - ProgressToken mcp.ProgressToken `json:"progressToken,omitempty"` - } `json:"_meta,omitempty"` - }{ + Params: mcp.CallToolParams{ Name: toolName, Arguments: arguments, }, From 1694f368373d29b308244658056ad6d91cf2b0ca Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 22:13:23 +0800 Subject: [PATCH 4/6] change: replace openai model with ark model --- go.mod | 8 +++----- go.sum | 21 +++++++++++++-------- uixt/ai/asserter.go | 18 +++++++++--------- uixt/ai/env.go | 12 +++++------- uixt/ai/planner.go | 9 +++++---- uixt/ai/querier.go | 23 ++++++++++++----------- 6 files changed, 47 insertions(+), 44 deletions(-) diff --git a/go.mod b/go.mod index b51fc5cb..ca680fc9 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,8 @@ require ( github.com/charmbracelet/huh/spinner v0.0.0-20250509124401-5fd7cf508477 github.com/charmbracelet/lipgloss v1.1.0 github.com/cloudwego/eino v0.3.47 - github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039 + github.com/cloudwego/eino-ext/components/model/ark v0.1.13 github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3 - github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8 github.com/danielpaulus/go-ios v1.0.161 github.com/denisbrodbeck/machineid v1.0.1 github.com/fatih/color v1.16.0 @@ -39,6 +38,7 @@ require ( github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 + github.com/volcengine/volcengine-go-sdk v1.1.16 golang.org/x/net v0.41.0 golang.org/x/term v0.32.0 golang.org/x/text v0.26.0 @@ -52,7 +52,6 @@ require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bytedance/mockey v1.2.14 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/catppuccin/go v0.2.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -68,7 +67,6 @@ require ( github.com/dlclark/regexp2 v1.11.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/evanphx/json-patch v0.5.2 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -103,7 +101,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/miekg/dns v1.1.57 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -134,6 +131,7 @@ require ( github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/volcengine/volc-sdk-golang v1.0.23 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yargevad/filepathx v1.0.0 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect diff --git a/go.sum b/go.sum index f69d5ecf..a4404074 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,7 @@ github.com/antchfx/xpath v1.3.3 h1:tmuPQa1Uye0Ym1Zn65vxPgfltWb/Lxu2jeqIGteJSRs= github.com/antchfx/xpath v1.3.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= @@ -72,12 +73,10 @@ github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCy github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/eino v0.3.47 h1:nl1Q1QZhFAyl169M32KZB8vj1Zp6fqeSjVF1lVzUSsw= github.com/cloudwego/eino v0.3.47/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039 h1:Lc074nJ801sh3Gg6FH8qJsBh0ZNQw6+kJRnYDikgK6c= -github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250626134119-cf4f96ea0039/go.mod h1:2mFQQnlhJrNgbW6YX1MOUUfXkGSbTz9Ylx37fbR0xBo= +github.com/cloudwego/eino-ext/components/model/ark v0.1.13 h1:gQYf6BOnknkoU1ZOx5CPRrLqsBQCpP/2YDZHvLPJdk4= +github.com/cloudwego/eino-ext/components/model/ark v0.1.13/go.mod h1:YBWArYd8ctuc4Zts2wEb/Q8iSxvTyHPq5zUQoHuY6OU= github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3 h1:kT8yynQh8q92BPofkHxxnXslJUj5AKex5+NpMrd+BU4= github.com/cloudwego/eino-ext/components/tool/mcp v0.0.3/go.mod h1:D1Yircehgx7em8EH6vw8If+ATjtXl60IpBzVaqFBx3c= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8 h1:WM3r11XwY39Ua8cH/LhGNr6vrzS73XEGxrAejN+C1dQ= -github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250703030129-4213de139ae8/go.mod h1:iB0W8l+OqKNL5LtJQ9JaGYXekhsxVxrDMfnfD9L+5gc= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= @@ -101,8 +100,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -169,6 +166,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -186,6 +184,7 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18= @@ -242,6 +241,7 @@ github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQe github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -277,8 +277,6 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde h1:pq2I0uxUR4lfr4OmqvE8QdHj9UML9b1jZu8L3dI2eu8= -github.com/meguminnnnnnnnn/go-openai v0.0.0-20250620092828-0d508a1dcdde/go.mod h1:CqSFsV6AkkL2fixd25WYjRAolns+gQrY1x/Cz9c30v8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= @@ -377,6 +375,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -393,6 +392,10 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/volcengine/volc-sdk-golang v1.0.23 h1:anOslb2Qp6ywnsbyq9jqR0ljuO63kg9PY+4OehIk5R8= +github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU= +github.com/volcengine/volcengine-go-sdk v1.1.16 h1:zaeKBnkLQdDdeYH1L+GsQM/PZBbXEuh7oiEypGTLHqY= +github.com/volcengine/volcengine-go-sdk v1.1.16/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= @@ -589,11 +592,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/uixt/ai/asserter.go b/uixt/ai/asserter.go index 2760f6ff..124f4d03 100644 --- a/uixt/ai/asserter.go +++ b/uixt/ai/asserter.go @@ -4,16 +4,17 @@ import ( "context" "fmt" - "github.com/cloudwego/eino-ext/components/model/openai" - openai2 "github.com/cloudwego/eino-ext/libs/acl/openai" + "github.com/cloudwego/eino-ext/components/model/ark" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/schema" "github.com/getkin/kin-openapi/openapi3gen" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + arkModel "github.com/volcengine/volcengine-go-sdk/service/arkruntime/model" + "github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/uixt/option" "github.com/httprunner/httprunner/v5/uixt/types" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" ) // IAsserter interface defines the contract for assertion operations @@ -65,10 +66,9 @@ func NewAsserter(ctx context.Context, modelConfig *ModelConfig) (*Asserter, erro return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } // set structured response format - // https://github.com/cloudwego/eino-ext/blob/main/components/model/openai/examples/structured/structured.go - modelConfig.ChatModelConfig.ResponseFormat = &openai2.ChatCompletionResponseFormat{ - Type: openai2.ChatCompletionResponseFormatTypeJSONSchema, - JSONSchema: &openai2.ChatCompletionResponseFormatJSONSchema{ + modelConfig.ChatModelConfig.ResponseFormat = &ark.ResponseFormat{ + Type: arkModel.ResponseFormatJSONSchema, + JSONSchema: &arkModel.ResponseFormatJSONSchemaJSONSchemaParam{ Name: "assertion_result", Description: "data that describes assertion result", Schema: outputFormatSchema.Value, @@ -78,7 +78,7 @@ func NewAsserter(ctx context.Context, modelConfig *ModelConfig) (*Asserter, erro } var err error - asserter.model, err = openai.NewChatModel(ctx, modelConfig.ChatModelConfig) + asserter.model, err = ark.NewChatModel(ctx, modelConfig.ChatModelConfig) if err != nil { return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } diff --git a/uixt/ai/env.go b/uixt/ai/env.go index 6018660d..3efff5b5 100644 --- a/uixt/ai/env.go +++ b/uixt/ai/env.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/cloudwego/eino-ext/components/model/openai" + "github.com/cloudwego/eino-ext/components/model/ark" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -21,9 +21,7 @@ const ( EnvModelName = "LLM_MODEL_NAME" ) -const ( - defaultTimeout = 120 * time.Second -) +var defaultTimeout = 120 * time.Second // GetModelConfig get OpenAI config func GetModelConfig(modelType option.LLMServiceType) (*ModelConfig, error) { @@ -39,11 +37,11 @@ func GetModelConfig(modelType option.LLMServiceType) (*ModelConfig, error) { // https://www.volcengine.com/docs/82379/1536429 temperature := float32(0) topP := float32(0.7) - modelConfig := &openai.ChatModelConfig{ + modelConfig := &ark.ChatModelConfig{ BaseURL: baseURL, APIKey: apiKey, Model: modelName, - Timeout: defaultTimeout, + Timeout: &defaultTimeout, Temperature: &temperature, TopP: &topP, } @@ -63,7 +61,7 @@ func GetModelConfig(modelType option.LLMServiceType) (*ModelConfig, error) { } type ModelConfig struct { - *openai.ChatModelConfig + *ark.ChatModelConfig ModelType option.LLMServiceType } diff --git a/uixt/ai/planner.go b/uixt/ai/planner.go index 337bb25c..6fae9ac6 100644 --- a/uixt/ai/planner.go +++ b/uixt/ai/planner.go @@ -3,14 +3,15 @@ package ai import ( "context" - "github.com/cloudwego/eino-ext/components/model/openai" + "github.com/cloudwego/eino-ext/components/model/ark" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/schema" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/uixt/option" "github.com/httprunner/httprunner/v5/uixt/types" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" ) type IPlanner interface { @@ -42,7 +43,7 @@ func NewPlanner(ctx context.Context, modelConfig *ModelConfig) (*Planner, error) } var err error - planner.model, err = openai.NewChatModel(ctx, modelConfig.ChatModelConfig) + planner.model, err = ark.NewChatModel(ctx, modelConfig.ChatModelConfig) if err != nil { return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } diff --git a/uixt/ai/querier.go b/uixt/ai/querier.go index 54194fad..770281f9 100644 --- a/uixt/ai/querier.go +++ b/uixt/ai/querier.go @@ -5,16 +5,17 @@ import ( "fmt" "reflect" - "github.com/cloudwego/eino-ext/components/model/openai" - openai2 "github.com/cloudwego/eino-ext/libs/acl/openai" + "github.com/cloudwego/eino-ext/components/model/ark" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/schema" "github.com/getkin/kin-openapi/openapi3gen" + "github.com/pkg/errors" + arkModel "github.com/volcengine/volcengine-go-sdk/service/arkruntime/model" + "github.com/httprunner/httprunner/v5/code" "github.com/httprunner/httprunner/v5/internal/json" "github.com/httprunner/httprunner/v5/uixt/option" "github.com/httprunner/httprunner/v5/uixt/types" - "github.com/pkg/errors" ) // IQuerier interface defines the contract for query operations @@ -68,9 +69,9 @@ func NewQuerier(ctx context.Context, modelConfig *ModelConfig) (*Querier, error) return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } // set structured response format - modelConfig.ChatModelConfig.ResponseFormat = &openai2.ChatCompletionResponseFormat{ - Type: openai2.ChatCompletionResponseFormatTypeJSONSchema, - JSONSchema: &openai2.ChatCompletionResponseFormatJSONSchema{ + modelConfig.ChatModelConfig.ResponseFormat = &ark.ResponseFormat{ + Type: arkModel.ResponseFormatJSONSchema, + JSONSchema: &arkModel.ResponseFormatJSONSchemaJSONSchemaParam{ Name: "query_result", Description: "data that describes query result", Schema: outputFormatSchema.Value, @@ -80,7 +81,7 @@ func NewQuerier(ctx context.Context, modelConfig *ModelConfig) (*Querier, error) } var err error - querier.model, err = openai.NewChatModel(ctx, modelConfig.ChatModelConfig) + querier.model, err = ark.NewChatModel(ctx, modelConfig.ChatModelConfig) if err != nil { return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } @@ -207,9 +208,9 @@ func (q *Querier) queryWithCustomSchema(ctx context.Context, opts *QueryOptions) } // Create custom response format with the provided schema - modelConfig.ChatModelConfig.ResponseFormat = &openai2.ChatCompletionResponseFormat{ - Type: openai2.ChatCompletionResponseFormatTypeJSONSchema, - JSONSchema: &openai2.ChatCompletionResponseFormatJSONSchema{ + modelConfig.ChatModelConfig.ResponseFormat = &ark.ResponseFormat{ + Type: arkModel.ResponseFormatJSONSchema, + JSONSchema: &arkModel.ResponseFormatJSONSchemaJSONSchemaParam{ Name: "custom_query_result", Description: "custom structured data response", Schema: outputFormatSchema.Value, @@ -219,7 +220,7 @@ func (q *Querier) queryWithCustomSchema(ctx context.Context, opts *QueryOptions) } // Create a new model instance with custom schema - model, err := openai.NewChatModel(ctx, modelConfig.ChatModelConfig) + model, err := ark.NewChatModel(ctx, modelConfig.ChatModelConfig) if err != nil { return nil, errors.Wrap(code.LLMPrepareRequestError, err.Error()) } From 2168ee0e69c34ec42405ee7778c8a02ea229f7bb Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 22:48:39 +0800 Subject: [PATCH 5/6] fix: dump summary with original variables for security --- config.go | 8 +++++--- runner.go | 10 +++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/config.go b/config.go index cbb165b5..9e20bb9a 100644 --- a/config.go +++ b/config.go @@ -14,9 +14,10 @@ type IConfig interface { // NewConfig returns a new constructed testcase config with specified testcase name. func NewConfig(name string) *TConfig { return &TConfig{ - Name: name, - Environs: make(map[string]string), - Variables: make(map[string]interface{}), + Name: name, + Environs: make(map[string]string), + Variables: make(map[string]interface{}), + OriginalVariables: make(map[string]interface{}), } } @@ -28,6 +29,7 @@ type TConfig struct { Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` // public request headers Environs map[string]string `json:"environs,omitempty" yaml:"environs,omitempty"` // environment variables Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` // global variables + OriginalVariables map[string]interface{} `json:"-" yaml:"-"` // original user variables before env merge (not serialized) Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"` ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"` ThinkTimeSetting *ThinkTimeConfig `json:"think_time,omitempty" yaml:"think_time,omitempty"` diff --git a/runner.go b/runner.go index 083218d5..62b266d0 100644 --- a/runner.go +++ b/runner.go @@ -459,6 +459,12 @@ func (r *CaseRunner) parseConfig() (parsedConfig *TConfig, err error) { } parsedConfig.Variables = parsedVariables + // backup original user variables before merging env variables + parsedConfig.OriginalVariables = make(map[string]interface{}) + for k, v := range parsedVariables { + parsedConfig.OriginalVariables[k] = v + } + // parse config name parsedName, err := r.parser.ParseString(cfg.Name, parsedVariables) if err != nil { @@ -694,7 +700,9 @@ func (r *SessionRunner) Start(givenVars map[string]interface{}) (summary *TestCa exportVars[value] = r.sessionVariables[value] } summary.InOut.ExportVars = exportVars - summary.InOut.ConfigVars = config.Variables + + // dump summary with original user variables only (exclude environment variables) + summary.InOut.ConfigVars = config.OriginalVariables // Save JSON case content to results directory if config.Path != "" { From a1a235d2b4fd6f701685273660acd28f78ce6df5 Mon Sep 17 00:00:00 2001 From: "lilong.129" Date: Thu, 3 Jul 2025 23:07:39 +0800 Subject: [PATCH 6/6] change: disable register tools for models with function calling --- uixt/ai/planner.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/uixt/ai/planner.go b/uixt/ai/planner.go index 6fae9ac6..09505d86 100644 --- a/uixt/ai/planner.go +++ b/uixt/ai/planner.go @@ -72,21 +72,21 @@ func (p *Planner) RegisterTools(tools []*schema.ToolInfo) error { return nil } - // register tools for models with function calling - toolCallingModel, err := p.model.WithTools(tools) - if err != nil { - return errors.Wrap(err, "failed to register tools") - } + // TODO: register tools for models with function calling + // toolCallingModel, err := p.model.WithTools(tools) + // if err != nil { + // return errors.Wrap(err, "failed to register tools") + // } - var toolNames []string - for _, tool := range tools { - toolNames = append(toolNames, tool.Name) - } - log.Debug().Strs("tools", toolNames). - Str("model", string(p.modelConfig.ModelType)). - Msg("registered tools to model") + // var toolNames []string + // for _, tool := range tools { + // toolNames = append(toolNames, tool.Name) + // } + // log.Debug().Strs("tools", toolNames). + // Str("model", string(p.modelConfig.ModelType)). + // Msg("registered tools to model") - p.model = toolCallingModel + // p.model = toolCallingModel return nil }