Class: ActionAgent::McpRecordingMiddleware

Inherits:
Object
  • Object
show all
Defined in:
app/services/action_agent/mcp_recording_middleware.rb

Overview

Middleware for recording MCP tool calls during browser automation

This middleware intercepts Playwright MCP tool calls and records them to a SessionRecording for playback and debugging.

Usage:

middleware = McpRecordingMiddleware.new(session_recording: recording)

# Process a tool call
result = middleware.intercept(tool_call) do
# Execute the actual MCP tool
mcp_client.call_tool(tool_call)
end

Constant Summary collapse

PLAYWRIGHT_TOOLS =

Map of Playwright MCP tool names to our action types

{
  "browser_navigate" => "navigate",
  "browser_click" => "click",
  "browser_type" => "type",
  "browser_fill_form" => "form_fill",
  "browser_press_key" => "key_press",
  "browser_snapshot" => "snapshot",
  "browser_take_screenshot" => "snapshot",
  "browser_hover" => "hover",
  "browser_select_option" => "select",
  "browser_file_upload" => "file_upload",
  "browser_handle_dialog" => "dialog",
  "browser_evaluate" => "evaluate",
  "browser_wait_for" => "wait",
  "browser_drag" => "drag",
  "browser_scroll" => "scroll"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(session_recording: nil, sandbox_session: nil, agent_run: nil) ⇒ McpRecordingMiddleware

Returns a new instance of McpRecordingMiddleware.



40
41
42
43
44
45
46
47
48
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 40

def initialize(session_recording: nil, sandbox_session: nil, agent_run: nil)
  @recording = session_recording
  @sandbox_session = sandbox_session
  @agent_run = agent_run

  # Create or find recording if not provided
  @recording ||= find_or_create_recording
  @recording_service = SessionRecordingService.new(@recording) if @recording
end

Instance Attribute Details

#recording_serviceObject (readonly)

Returns the value of attribute recording_service.



38
39
40
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 38

def recording_service
  @recording_service
end

Instance Method Details

#capture_for_handoff(url:, cookies: nil, local_storage: nil, form_values: nil) ⇒ Object

Record current page state for handoff



101
102
103
104
105
106
107
108
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 101

def capture_for_handoff(url:, cookies: nil, local_storage: nil, form_values: nil)
  @recording_service&.capture_handoff_state(
    url: url,
    cookies: cookies,
    local_storage: local_storage,
    form_values: form_values
  )
end

#complete!Object

Complete the recording



111
112
113
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 111

def complete!
  @recording_service&.complete!
end

#fail!(error_message = nil) ⇒ Object

Fail the recording



116
117
118
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 116

def fail!(error_message = nil)
  @recording_service&.fail!(error_message)
end

#intercept(tool_name:, parameters:) ⇒ Object

Intercept an MCP tool call and record it



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 51

def intercept(tool_name:, parameters:)
  action_type = PLAYWRIGHT_TOOLS[tool_name]

  # If not a Playwright tool, just execute and return
  unless action_type
    return yield if block_given?
    return nil
  end

  # Execute the tool
  result = nil
  screenshot = nil
  error = nil

  begin
    result = yield if block_given?

    # Extract screenshot from result if present
    screenshot = extract_screenshot(result)
  rescue => e
    error = e.message
    raise
  ensure
    # Record the action
    record_action(action_type, tool_name, parameters, result, screenshot, error)
  end

  result
end

#record_click(selector:, screenshot: nil, element_description: nil) ⇒ Object

Convenience method for recording a click



87
88
89
90
91
92
93
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 87

def record_click(selector:, screenshot: nil, element_description: nil)
  @recording_service&.click(
    selector: selector,
    screenshot: screenshot,
    metadata: { element: element_description }.compact
  )
end

#record_navigate(url:, screenshot: nil) ⇒ Object

Convenience method for recording a navigation



82
83
84
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 82

def record_navigate(url:, screenshot: nil)
  @recording_service&.navigate(url: url, screenshot: screenshot)
end

#record_type(selector:, text:, screenshot: nil) ⇒ Object

Convenience method for recording text input



96
97
98
# File 'app/services/action_agent/mcp_recording_middleware.rb', line 96

def record_type(selector:, text:, screenshot: nil)
  @recording_service&.type(selector: selector, text: text, screenshot: screenshot)
end