Class: Html2rss::MCP::Outcome

Inherits:
Data
  • Object
show all
Defined in:
lib/html2rss/mcp/outcome.rb,
lib/html2rss/mcp/outcome.rb,
lib/html2rss/mcp/outcome/playbook.rb

Overview

Typed MCP tool result. Owns next-step policy; guidance copy lives in Playbook.

Defined Under Namespace

Classes: NextStep, Playbook

Constant Summary collapse

XOR_ERROR =

Matches ConfigArgument XOR ArgumentError messages.

/exactly one of config or yaml/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ok:, next_step:, guidance:, payload:) ⇒ Outcome

Returns a new instance of Outcome.

Parameters:

  • ok (Boolean)
  • next_step (NextStep)
  • guidance (String)
  • payload (Hash)

Raises:

  • (ArgumentError)


41
42
43
44
45
46
# File 'lib/html2rss/mcp/outcome.rb', line 41

def initialize(ok:, next_step:, guidance:, payload:) # rubocop:disable Naming/MethodParameterName -- +ok+ is the envelope field
  raise ArgumentError, 'next_step must be a NextStep' unless next_step.is_a?(NextStep)
  raise ArgumentError, 'payload must be a Hash' unless payload.is_a?(Hash)

  super(ok: !!ok, next_step:, guidance: guidance.to_s.freeze, payload: payload.dup.freeze)
end

Instance Attribute Details

#guidanceObject (readonly)

Returns the value of attribute guidance

Returns:

  • (Object)

    the current value of guidance



5
6
7
# File 'lib/html2rss/mcp/outcome.rb', line 5

def guidance
  @guidance
end

#next_stepObject (readonly)

Returns the value of attribute next_step

Returns:

  • (Object)

    the current value of next_step



5
6
7
# File 'lib/html2rss/mcp/outcome.rb', line 5

def next_step
  @next_step
end

#okObject (readonly)

Returns the value of attribute ok

Returns:

  • (Object)

    the current value of ok



5
6
7
# File 'lib/html2rss/mcp/outcome.rb', line 5

def ok
  @ok
end

#payloadObject (readonly)

Returns the value of attribute payload

Returns:

  • (Object)

    the current value of payload



5
6
7
# File 'lib/html2rss/mcp/outcome.rb', line 5

def payload
  @payload
end

Class Method Details

.apply(rss:, item_count:, empty: item_count.zero?, quality_report: nil) ⇒ Outcome

Parameters:

  • rss (String)
  • item_count (Integer)
  • empty (Boolean) (defaults to: item_count.zero?)

    FeedResult#empty? (ship gate); defaults to zero items

  • quality_report (Hash, nil) (defaults to: nil)

    optional ship-quality audit summary

Returns:



152
153
154
155
156
157
158
# File 'lib/html2rss/mcp/outcome.rb', line 152

def apply(rss:, item_count:, empty: item_count.zero?, quality_report: nil)
  ok = !empty
  next_step = ok ? NextStep.done : NextStep.inspect
  payload = { rss:, item_count: }
  payload[:quality_report] = quality_report if quality_report
  new(ok:, next_step:, guidance: next_step.guidance, payload:)
end

.batch_inspect(batch_result) ⇒ Outcome

Parameters:

Returns:



139
# File 'lib/html2rss/mcp/outcome.rb', line 139

def batch_inspect(batch_result) = batch(batch_result, NextStep.inspect)

.batch_recon(batch_result) ⇒ Outcome

Parameters:

Returns:



144
# File 'lib/html2rss/mcp/outcome.rb', line 144

def batch_recon(batch_result) = batch(batch_result, NextStep.recon)

.batch_scrape(batch_result) ⇒ Outcome

Parameters:

Returns:



134
# File 'lib/html2rss/mcp/outcome.rb', line 134

def batch_scrape(batch_result) = batch(batch_result, NextStep.scrape)

.capture(yaml:, articles_count:, has_selectors:, channel_title:, requested_strategy:, segment_strategy: nil, selected_strategy: nil, admission_drops: {}, native_feed: nil, suggested_channel_url: nil) ⇒ Outcome

Parameters:

  • yaml (String)
  • articles_count (Integer)
  • has_selectors (Boolean)
  • channel_title (String, nil)
  • requested_strategy (String, Symbol)
  • segment_strategy (Symbol, String, nil) (defaults to: nil)
  • selected_strategy (Symbol, String, nil) (defaults to: nil)
  • admission_drops (Hash) (defaults to: {})
  • native_feed (String, nil) (defaults to: nil)
  • suggested_channel_url (String, nil) (defaults to: nil)

Returns:



98
99
100
101
102
103
104
105
106
107
# File 'lib/html2rss/mcp/outcome.rb', line 98

def capture(yaml:, articles_count:, has_selectors:, channel_title:, requested_strategy:, # rubocop:disable Metrics/ParameterLists
            segment_strategy: nil, selected_strategy: nil, admission_drops: {}, native_feed: nil,
            suggested_channel_url: nil)
  next_step = capture_next_step(articles_count:, has_selectors:, native_feed:)
  new(ok: true, next_step:, guidance: next_step.guidance, payload: capture_payload(
    yaml:, articles_count:, has_selectors:, channel_title:, requested_strategy:,
    segment_strategy:, selected_strategy:, admission_drops:, native_feed:,
    suggested_channel_url:
  ))
end

.from_error(error) ⇒ Outcome

Parameters:

  • error (Exception)

Returns:



163
164
165
166
167
# File 'lib/html2rss/mcp/outcome.rb', line 163

def from_error(error)
  next_step = next_step_for_error(error)
  new(ok: false, next_step:, guidance: next_step.guidance,
      payload: { class: error.class.name, message: error.message })
end

.inspect(report:) ⇒ Outcome

Parameters:

Returns:



71
72
73
74
75
# File 'lib/html2rss/mcp/outcome.rb', line 71

def inspect(report:)
  next_step = inspect_next_step(report)
  guidance = Playbook.inspect_guidance(report)
  new(ok: true, next_step:, guidance:, payload: report.to_wire_h)
end

.recon(result:) ⇒ Outcome

Parameters:

Returns:



80
81
82
83
84
# File 'lib/html2rss/mcp/outcome.rb', line 80

def recon(result:)
  next_step = recon_next_step(result)
  guidance = Playbook.recon_guidance(result, next_step)
  new(ok: true, next_step:, guidance:, payload: result.to_h)
end

.scrape(items:, requested_strategy:, channel_title:, botasaurus_configured:, admission_drops: {}) ⇒ Outcome

Parameters:

  • items (Array)
  • requested_strategy (String, Symbol)
  • channel_title (String, nil)
  • admission_drops (Hash) (defaults to: {})
  • botasaurus_configured (Boolean)

Returns:



62
63
64
65
66
# File 'lib/html2rss/mcp/outcome.rb', line 62

def scrape(items:, requested_strategy:, channel_title:, botasaurus_configured:, admission_drops: {})
  next_step = scrape_next_step(items.empty?, botasaurus_configured:)
  new(ok: true, next_step:, guidance: next_step.guidance,
      payload: scrape_payload(items:, requested_strategy:, channel_title:, admission_drops:))
end

.test(test_result) ⇒ Outcome

Parameters:

Returns:



121
122
123
124
125
126
127
128
129
# File 'lib/html2rss/mcp/outcome.rb', line 121

def test(test_result)
  next_step = test_next_step(test_result)
  new(
    ok: test_result.success,
    next_step:,
    guidance: test_guidance(test_result, next_step),
    payload: test_result.to_h
  )
end

.validate(errors:) ⇒ Outcome

Parameters:

  • errors (Hash, nil)

    schema errors; nil means success

Returns:



112
113
114
115
116
# File 'lib/html2rss/mcp/outcome.rb', line 112

def validate(errors:)
  ok = errors.nil?
  next_step = ok ? NextStep.test : NextStep.validate
  new(ok:, next_step:, guidance: next_step.guidance, payload: ok ? {} : { errors: })
end

Instance Method Details

#to_hHash{Symbol => Object}

Returns envelope for Contract.response.

Returns:



50
51
52
# File 'lib/html2rss/mcp/outcome.rb', line 50

def to_h
  { ok:, next_step: next_step.name.to_s, guidance:, payload: }
end