Class: Parse::Agent::MCPElicitationGate
- Inherits:
-
ApprovalGate
- Object
- ApprovalGate
- Parse::Agent::MCPElicitationGate
- 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
Instance Method Summary collapse
-
#initialize(correlation_id:, pending:, publish:, capability_check:, listener_check:, timeout: 30, id_generator: -> { SecureRandom.uuid }) ⇒ MCPElicitationGate
constructor
A new instance of MCPElicitationGate.
-
#review(tool_name:, effective_permission:, preview:, agent:) ⇒ Object
Wraps the elicitation round-trip in a
parse.agent.approvalActiveSupport::Notifications event so operators can observe approval latency and outcomes — including a non-answering client that holds a dispatcher thread for the fulltimeout.
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: , correlation_id: @correlation_id, timeout: @timeout, } ActiveSupport::Notifications.instrument("parse.agent.approval", payload) do decision = perform_review(tool_name, , preview) payload[:outcome] = decision.outcome payload[:reason] = decision.reason decision end end |