Class: Parse::Agent::MCPElicitationGate

Inherits:
ApprovalGate show all
Defined in:
lib/parse/agent/approval_gate.rb

Overview

Spec-native MCP elicitation gate. On #review it pushes an elicitation/create JSON-RPC request to the client over the GET listening stream and blocks (bounded by timeout) for the client's reply, which arrives as a separate POST routed into PendingElicitationRegistry.

Collaborators are injected (not transport objects) so the gate is unit-testable without a live connection:

Constant Summary

Constants inherited from ApprovalGate

ApprovalGate::ABORT

Instance Method Summary collapse

Constructor Details

#initialize(correlation_id:, pending:, publish:, capability_check:, listener_check:, timeout: 30, id_generator: -> { SecureRandom.uuid }) ⇒ MCPElicitationGate

Returns a new instance of MCPElicitationGate.



196
197
198
199
200
201
202
203
204
205
206
# File 'lib/parse/agent/approval_gate.rb', line 196

def initialize(correlation_id:, pending:, publish:, capability_check:,
               listener_check:, timeout: 30,
               id_generator: -> { SecureRandom.uuid })
  @correlation_id = correlation_id
  @pending = pending
  @publish = publish
  @capability_check = capability_check
  @listener_check = listener_check
  @timeout = timeout
  @id_generator = id_generator
end

Instance Method Details

#review(tool_name:, effective_permission:, preview:, agent:) ⇒ Object

Wraps the elicitation round-trip in a parse.agent.approval ActiveSupport::Notifications event so operators can observe approval latency and outcomes — including a non-answering client that holds a dispatcher thread for the full timeout. The event's measured duration is the wait time; the payload carries the outcome and reason.



213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/parse/agent/approval_gate.rb', line 213

def review(tool_name:, effective_permission:, preview:, agent:)
  payload = {
    tool: tool_name,
    effective_permission: effective_permission,
    correlation_id: @correlation_id,
    timeout: @timeout,
  }
  ActiveSupport::Notifications.instrument("parse.agent.approval", payload) do
    decision = perform_review(tool_name, effective_permission, preview)
    payload[:outcome] = decision.outcome
    payload[:reason]  = decision.reason
    decision
  end
end