Module: RailsAiContext::Tools::SectionFetch

Included in:
BaseTool
Defined in:
lib/rails_ai_context/tools/section_fetch.rb

Overview

Asking for an introspection section and answering honestly when it is unusable are one operation. A tool names the section and what to call it; everything that could make the answer dishonest - the section was never introspected, the introspector raised, the data source was absent, the app is API-only, the tier cannot serve it - is handled here, and the block only ever sees real data.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.usable?(data) ⇒ Boolean

Whether a section can be rendered at all: a hash carrying :error (the introspector raised) or :unavailable (the data source was absent) is not empty data, it is no data. The serializers ask through Serializers::SectionGuard, which defers here.

Returns:

  • (Boolean)


16
17
18
# File 'lib/rails_ai_context/tools/section_fetch.rb', line 16

def self.usable?(data)
  data.is_a?(Hash) && !data[:error] && !data[:unavailable]
end

Instance Method Details

#fetch_section(key, subject: nil, remedy: nil, api_only: nil, unusable_message: nil) {|data| ... } ⇒ Object

Returns the block's value, or a text response explaining why not.

Parameters:

  • unusable_message (String) (defaults to: nil)

    one answer for both "never introspected" and "the introspector raised", for tools that do not distinguish them.

Yields:

  • (data)

Returns:

  • the block's value, or a text response explaining why not.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rails_ai_context/tools/section_fetch.rb', line 24

def fetch_section(key, subject: nil, remedy: nil, api_only: nil, unusable_message: nil)
  if (refusal = static_refusal_for(key))
    return refusal
  end

  data = cached_context[key]
  unless data.is_a?(Hash) && !data[:error]
    if (note = unavailable_note(data))
      return text_response(note)
    end

    return text_response(unusable_message) if unusable_message

    # Anything that is not a hash is not a section this tool can read,
    # and asking it for `[:error]` raises - which SafeCall would then
    # report as the tool failing, the dishonest answer this seam exists
    # to prevent.
    unless data.is_a?(Hash)
      return text_response("#{subject} not available. #{remedy || "Add :#{key} to introspectors."}")
    end

    return text_response("#{subject} failed: #{data[:error]}")
  end

  if (note = unavailable_note(data))
    return text_response(note)
  end

  if api_only && (note = api_only_note(api_only))
    return text_response(note)
  end

  yield data
end