Module: RubyLLM::Support::Utils

Defined in:
lib/ruby_llm/support/utils.rb

Overview

:nodoc:

Constant Summary collapse

UNDERSCORE_BOUNDARY =
/(?<=[a-z\d])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/
SCHEMA_METADATA_KEYS =

Keys a JSON Schema document carries for its own sake: $schema names the dialect and title names the document, neither of which describes the shape a provider is being asked to produce.

%w[$schema title].freeze

Class Method Summary collapse

Class Method Details

.deep_dup(value) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ruby_llm/support/utils.rb', line 100

def deep_dup(value)
  case value
  when Hash
    value.each_with_object({}) do |(key, val), duped|
      duped[deep_dup(key)] = deep_dup(val)
    end
  when Array
    value.map { |item| deep_dup(item) }
  else
    begin
      value.dup
    rescue TypeError
      value
    end
  end
end

.deep_merge(original, overrides) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/ruby_llm/support/utils.rb', line 90

def deep_merge(original, overrides)
  original.merge(overrides) do |_key, original_value, overrides_value|
    if original_value.is_a?(Hash) && overrides_value.is_a?(Hash)
      deep_merge(original_value, overrides_value)
    else
      overrides_value
    end
  end
end

.deep_stringify_keys(value) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ruby_llm/support/utils.rb', line 117

def deep_stringify_keys(value)
  case value
  when Hash
    value.each_with_object({}) do |(key, val), result|
      result[key.to_s] = deep_stringify_keys(val)
    end
  when Array
    value.map { |item| deep_stringify_keys(item) }
  when Symbol
    value.to_s
  else
    value
  end
end

.deep_symbolize_keys(value) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/ruby_llm/support/utils.rb', line 132

def deep_symbolize_keys(value)
  case value
  when Hash
    value.each_with_object({}) do |(key, val), result|
      symbolized_key = key.respond_to?(:to_sym) ? key.to_sym : key
      result[symbolized_key] = deep_symbolize_keys(val)
    end
  when Array
    value.map { |item| deep_symbolize_keys(item) }
  else
    value
  end
end

.hash_get(hash, key) ⇒ Object



15
16
17
18
# File 'lib/ruby_llm/support/utils.rb', line 15

def hash_get(hash, key)
  symbol_key = key.to_sym
  hash.key?(symbol_key) ? hash[symbol_key] : hash[key.to_s]
end

.iso_date_prefix_to_utc_midnight_string(value) ⇒ Object



85
86
87
88
# File 'lib/ruby_llm/support/utils.rb', line 85

def iso_date_prefix_to_utc_midnight_string(value)
  date = parse_iso_date_prefix(value)
  "#{date.strftime('%Y-%m-%d')} 00:00:00 UTC" if date
end

.parse_iso_date_prefix(value) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ruby_llm/support/utils.rb', line 67

def parse_iso_date_prefix(value)
  return value if value.is_a?(Date)

  date = value.to_s.strip
  return if date.empty?

  case date
  when /\A\d{4}-\d{2}-\d{2}\z/
    Date.iso8601(date)
  when /\A\d{4}-\d{2}\z/
    Date.iso8601("#{date}-01")
  when /\A\d{4}\z/
    Date.iso8601("#{date}-01-01")
  end
rescue ArgumentError
  nil
end

.safe_constantize(name) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ruby_llm/support/utils.rb', line 51

def safe_constantize(name)
  parts = name.to_s.split('::').reject(&:empty?)
  return if parts.empty?

  namespace = Object
  until parts.empty?
    const_name = parts.shift
    return unless namespace.const_defined?(const_name, false)

    namespace = namespace.const_get(const_name, false)
  end
  namespace
rescue NameError
  nil
end

.strip_schema_metadata(schema) ⇒ Object



20
21
22
23
24
# File 'lib/ruby_llm/support/utils.rb', line 20

def (schema)
  return schema unless schema.is_a?(Hash)

  schema.reject { |key, _| SCHEMA_METADATA_KEYS.include?(key.to_s) }
end

.to_date(value) ⇒ Object



45
46
47
48
49
# File 'lib/ruby_llm/support/utils.rb', line 45

def to_date(value)
  return unless value

  value.is_a?(Date) ? value : Date.parse(value.to_s)
end

.to_safe_array(item) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/ruby_llm/support/utils.rb', line 31

def to_safe_array(item)
  case item
  when Array then item
  when Hash then [item]
  else item.respond_to?(:read) ? [item] : Array(item)
  end
end

.to_time(value) ⇒ Object



39
40
41
42
43
# File 'lib/ruby_llm/support/utils.rb', line 39

def to_time(value)
  return unless value

  value.is_a?(Time) ? value : Time.parse(value.to_s)
end

.underscore(name) ⇒ Object

Acronym-aware underscoring: 'HTTPProxyTool' -> 'http_proxy_tool'.



27
28
29
# File 'lib/ruby_llm/support/utils.rb', line 27

def underscore(name)
  name.gsub(UNDERSCORE_BOUNDARY, '_').downcase
end