Module: AgUiProtocol::Util

Extended by:
T::Sig
Defined in:
lib/ag_ui_protocol/util.rb

Overview

Utility methods for encoding events.

Defined Under Namespace

Classes: Opaque

Class Method Summary collapse

Class Method Details

.camelize_key(key) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/ag_ui_protocol/util.rb', line 62

def camelize_key(key)
  str = key.to_s
  parts = str.split("_")
  return str if parts.length <= 1

  parts[0] + parts[1..].map { |p| p.empty? ? "" : (p[0].upcase + p[1..]) }.join
end

.deep_compact(value) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ag_ui_protocol/util.rb', line 73

def deep_compact(value)
  value = normalize_value(value)
  case value
  when Opaque
    # Opaque payloads are pass-through: do not recurse into their content
    # and do not strip nils. The wrapper is unwrapped during camelization.
    value
  when Hash
    value.transform_values { |v| deep_compact(v) unless v.nil? }.tap(&:compact!)
  when Array
    tmp1 = value.map { |v| deep_compact(v) }
    tmp1.reject!(&:nil?)
    tmp1
  else
    value
  end
end

.deep_transform_keys_to_camel(value) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ag_ui_protocol/util.rb', line 94

def deep_transform_keys_to_camel(value)
  value = normalize_value(value)
  case value
  when Opaque
    # Unwrap and emit the inner value verbatim — keys (including nested
    # Hash keys and Array elements) are preserved as supplied by the user.
    value.value
  when Hash
    value.each_with_object({}) do |(k, v), acc|
      acc[camelize_key(k)] = deep_transform_keys_to_camel(v)
    end
  when Array
    value.map { |v| deep_transform_keys_to_camel(v) }
  else
    value
  end
end

.dump_json(value) ⇒ Object



115
116
117
# File 'lib/ag_ui_protocol/util.rb', line 115

def dump_json(value)
  JSON.generate(value)
end

.normalize_value(value) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ag_ui_protocol/util.rb', line 42

def normalize_value(value)
  case value
  when Opaque
    # Preserve the wrapper so downstream stages can recognize and skip it.
    value
  when Time
    # AG-UI protocol wire format for BaseEvent.timestamp is epoch
    # milliseconds (matches Python SDK `Optional[int]` and TypeScript
    # `z.number().optional()`).
    (value.to_f * 1000).to_i
  when AgUiProtocol::Core::Types::Model
    value.to_h
  else
    value
  end
end