mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 23:51:25 +08:00
feat: optimize MCP tools response format with automatic schema generation
- Remove all manual ReturnSchema() methods from tools - Implement automatic schema generation using reflection - Unify response format to flat structure with action/success/message fields - Simplify tool implementation by removing MCPResponse embedding - Update documentation to reflect new architecture - Achieve ~70% code reduction while maintaining type safety
This commit is contained in:
+40
-38
@@ -14,7 +14,11 @@ import (
|
||||
)
|
||||
|
||||
// ToolSleep implements the sleep tool call.
|
||||
type ToolSleep struct{}
|
||||
type ToolSleep struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
Seconds float64 `json:"seconds" desc:"Duration in seconds that was slept"`
|
||||
Duration string `json:"duration" desc:"Human-readable duration string"`
|
||||
}
|
||||
|
||||
func (t *ToolSleep) Name() option.ActionName {
|
||||
return option.ACTION_Sleep
|
||||
@@ -42,18 +46,23 @@ func (t *ToolSleep) Implement() server.ToolHandlerFunc {
|
||||
log.Info().Interface("seconds", seconds).Msg("sleeping")
|
||||
|
||||
var duration time.Duration
|
||||
var actualSeconds float64
|
||||
switch v := seconds.(type) {
|
||||
case float64:
|
||||
actualSeconds = v
|
||||
duration = time.Duration(v*1000) * time.Millisecond
|
||||
case int:
|
||||
actualSeconds = float64(v)
|
||||
duration = time.Duration(v) * time.Second
|
||||
case int64:
|
||||
actualSeconds = float64(v)
|
||||
duration = time.Duration(v) * time.Second
|
||||
case string:
|
||||
s, err := builtin.ConvertToFloat64(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid sleep duration: %v", v)
|
||||
}
|
||||
actualSeconds = s
|
||||
duration = time.Duration(s*1000) * time.Millisecond
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported sleep duration type: %T", v)
|
||||
@@ -61,7 +70,13 @@ func (t *ToolSleep) Implement() server.ToolHandlerFunc {
|
||||
|
||||
time.Sleep(duration)
|
||||
|
||||
return mcp.NewToolResultText(fmt.Sprintf("Successfully slept for %v seconds", seconds)), nil
|
||||
message := fmt.Sprintf("Successfully slept for %v seconds", actualSeconds)
|
||||
returnData := ToolSleep{
|
||||
Seconds: actualSeconds,
|
||||
Duration: duration.String(),
|
||||
}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,15 +87,11 @@ func (t *ToolSleep) ConvertActionToCallToolRequest(action option.MobileAction) (
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolSleep) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming sleep operation completed",
|
||||
"seconds": "float64: Duration in seconds that was slept",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSleepMS implements the sleep_ms tool call.
|
||||
type ToolSleepMS struct{}
|
||||
type ToolSleepMS struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
Milliseconds int64 `json:"milliseconds" desc:"Duration in milliseconds that was slept"`
|
||||
}
|
||||
|
||||
func (t *ToolSleepMS) Name() option.ActionName {
|
||||
return option.ACTION_SleepMS
|
||||
@@ -111,7 +122,10 @@ func (t *ToolSleepMS) Implement() server.ToolHandlerFunc {
|
||||
log.Info().Int64("milliseconds", unifiedReq.Milliseconds).Msg("sleeping in milliseconds")
|
||||
time.Sleep(time.Duration(unifiedReq.Milliseconds) * time.Millisecond)
|
||||
|
||||
return mcp.NewToolResultText(fmt.Sprintf("Successfully slept for %d milliseconds", unifiedReq.Milliseconds)), nil
|
||||
message := fmt.Sprintf("Successfully slept for %d milliseconds", unifiedReq.Milliseconds)
|
||||
returnData := ToolSleepMS{Milliseconds: unifiedReq.Milliseconds}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,15 +144,11 @@ func (t *ToolSleepMS) ConvertActionToCallToolRequest(action option.MobileAction)
|
||||
return buildMCPCallToolRequest(t.Name(), arguments), nil
|
||||
}
|
||||
|
||||
func (t *ToolSleepMS) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming sleep operation completed",
|
||||
"milliseconds": "int64: Duration in milliseconds that was slept",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolSleepRandom implements the sleep_random tool call.
|
||||
type ToolSleepRandom struct{}
|
||||
type ToolSleepRandom struct {
|
||||
// Return data fields - these define the structure of data returned by this tool
|
||||
Params []float64 `json:"params" desc:"Random sleep parameters used"`
|
||||
}
|
||||
|
||||
func (t *ToolSleepRandom) Name() option.ActionName {
|
||||
return option.ACTION_SleepRandom
|
||||
@@ -163,7 +173,10 @@ func (t *ToolSleepRandom) Implement() server.ToolHandlerFunc {
|
||||
// Sleep random action logic
|
||||
sleepStrict(time.Now(), getSimulationDuration(unifiedReq.Params))
|
||||
|
||||
return mcp.NewToolResultText(fmt.Sprintf("Successfully slept for random duration with params: %v", unifiedReq.Params)), nil
|
||||
message := fmt.Sprintf("Successfully slept for random duration with params: %v", unifiedReq.Params)
|
||||
returnData := ToolSleepRandom{Params: unifiedReq.Params}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,16 +190,9 @@ func (t *ToolSleepRandom) ConvertActionToCallToolRequest(action option.MobileAct
|
||||
return mcp.CallToolRequest{}, fmt.Errorf("invalid sleep random params: %v", action.Params)
|
||||
}
|
||||
|
||||
func (t *ToolSleepRandom) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming random sleep operation completed",
|
||||
"params": "[]float64: Parameters used for random duration calculation",
|
||||
"actualDuration": "float64: Actual duration that was slept (in seconds)",
|
||||
}
|
||||
}
|
||||
|
||||
// ToolClosePopups implements the close_popups tool call.
|
||||
type ToolClosePopups struct{}
|
||||
type ToolClosePopups struct { // Return data fields - these define the structure of data returned by this tool
|
||||
}
|
||||
|
||||
func (t *ToolClosePopups) Name() option.ActionName {
|
||||
return option.ACTION_ClosePopups
|
||||
@@ -211,20 +217,16 @@ func (t *ToolClosePopups) Implement() server.ToolHandlerFunc {
|
||||
// Close popups action logic
|
||||
err = driverExt.ClosePopupsHandler()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("Close popups failed: %s", err.Error())), nil
|
||||
return NewMCPErrorResponse(fmt.Sprintf("Close popups failed: %s", err.Error())), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText("Successfully closed popups"), nil
|
||||
message := "Successfully closed popups"
|
||||
returnData := ToolClosePopups{}
|
||||
|
||||
return NewMCPSuccessResponse(message, &returnData), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ToolClosePopups) ConvertActionToCallToolRequest(action option.MobileAction) (mcp.CallToolRequest, error) {
|
||||
return buildMCPCallToolRequest(t.Name(), map[string]any{}), nil
|
||||
}
|
||||
|
||||
func (t *ToolClosePopups) ReturnSchema() map[string]string {
|
||||
return map[string]string{
|
||||
"message": "string: Success message confirming popups were closed",
|
||||
"popupsClosed": "int: Number of popup windows or dialogs that were closed",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user