ag-ui-protocol 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,11 +39,10 @@ module AgUiProtocol
39
39
  # ### Implementation Details
40
40
  #
41
41
  # Internally, the encoder converts events to JSON and formats them as Server-Sent
42
- # Events with the following structure:
42
+ # Events with the following structure (each event terminated by two literal
43
+ # newline characters, shown here as escape sequences):
43
44
  #
44
- # ```
45
- # data: {json-serialized event}\n\n
46
- # ```
45
+ # data: {json-serialized event}\n\n
47
46
  #
48
47
  # This format allows clients to receive a continuous stream of events and process
49
48
  # them as they arrive.
@@ -8,13 +8,48 @@ module AgUiProtocol
8
8
  # Utility methods for encoding events.
9
9
  module Util
10
10
  extend T::Sig
11
+
12
+ # Marks a value as opaque user-supplied payload that MUST pass through
13
+ # serialization unchanged — no key camelization, no nil compaction, no
14
+ # recursive normalization.
15
+ #
16
+ # Use this for fields where the AG-UI protocol carries arbitrary
17
+ # user-defined Hash content (e.g., `metadata`, `custom`, `response_schema`,
18
+ # JSON Patch op payloads, raw upstream events). Schema-typed fields whose
19
+ # keys are part of the protocol contract MUST NOT be wrapped — those still
20
+ # need camelCase rewriting on the wire.
21
+ #
22
+ # The wrapper unwraps to its original `value` at the camelization boundary
23
+ # in {Util.deep_transform_keys_to_camel}. Keys inside the wrapped value
24
+ # (and any nested Hashes/Arrays within it) are preserved verbatim.
25
+ class Opaque
26
+ extend T::Sig
27
+
28
+ sig { returns(T.untyped) }
29
+ attr_reader :value
30
+
31
+ sig { params(value: T.untyped).void }
32
+ def initialize(value)
33
+ @value = value
34
+ end
35
+ end
36
+
11
37
  module_function
12
38
 
13
39
  # @param value [Object]
14
40
  # @return [Object]
15
41
  sig { params(value: T.untyped).returns(T.untyped) }
16
42
  def normalize_value(value)
17
- if value.is_a?(AgUiProtocol::Core::Types::Model)
43
+ case value
44
+ when Opaque
45
+ # Preserve the wrapper so downstream stages can recognize and skip it.
46
+ value
47
+ when Time
48
+ # AG-UI protocol wire format for BaseEvent.timestamp is epoch
49
+ # milliseconds (matches Python SDK `Optional[int]` and TypeScript
50
+ # `z.number().optional()`).
51
+ (value.to_f * 1000).to_i
52
+ when AgUiProtocol::Core::Types::Model
18
53
  value.to_h
19
54
  else
20
55
  value
@@ -38,6 +73,10 @@ module AgUiProtocol
38
73
  def deep_compact(value)
39
74
  value = normalize_value(value)
40
75
  case value
76
+ when Opaque
77
+ # Opaque payloads are pass-through: do not recurse into their content
78
+ # and do not strip nils. The wrapper is unwrapped during camelization.
79
+ value
41
80
  when Hash
42
81
  value.transform_values { |v| deep_compact(v) unless v.nil? }.tap(&:compact!)
43
82
  when Array
@@ -55,6 +94,10 @@ module AgUiProtocol
55
94
  def deep_transform_keys_to_camel(value)
56
95
  value = normalize_value(value)
57
96
  case value
97
+ when Opaque
98
+ # Unwrap and emit the inner value verbatim — keys (including nested
99
+ # Hash keys and Array elements) are preserved as supplied by the user.
100
+ value.value
58
101
  when Hash
59
102
  value.each_with_object({}) do |(k, v), acc|
60
103
  acc[camelize_key(k)] = deep_transform_keys_to_camel(v)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module AgUiProtocol
4
4
  # The version of the protocol.
5
- VERSION = "0.1.5"
5
+ VERSION = "0.2.0"
6
6
  end
@@ -7,6 +7,7 @@ require_relative "ag_ui_protocol/version"
7
7
  require_relative "ag_ui_protocol/util"
8
8
  require_relative "ag_ui_protocol/core/types"
9
9
  require_relative "ag_ui_protocol/core/events"
10
+ require_relative "ag_ui_protocol/core/capabilities"
10
11
  require_relative "ag_ui_protocol/encoder/event_encoder"
11
12
 
12
13
  module AgUiProtocol
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ag-ui-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Buk
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-02-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: json
@@ -146,6 +145,7 @@ extra_rdoc_files: []
146
145
  files:
147
146
  - lib/ag-ui-protocol.rb
148
147
  - lib/ag_ui_protocol.rb
148
+ - lib/ag_ui_protocol/core/capabilities.rb
149
149
  - lib/ag_ui_protocol/core/events.rb
150
150
  - lib/ag_ui_protocol/core/types.rb
151
151
  - lib/ag_ui_protocol/encoder/event_encoder.rb
@@ -160,7 +160,6 @@ metadata:
160
160
  documentation_uri: https://github.com/ag-ui-protocol/ag-ui/blob/main/sdks/community/ruby/README.md
161
161
  changelog_uri: https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/ruby/CHANGELOG.md
162
162
  homepage_uri: https://docs.ag-ui.com/introduction
163
- post_install_message:
164
163
  rdoc_options: []
165
164
  require_paths:
166
165
  - lib
@@ -175,8 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
174
  - !ruby/object:Gem::Version
176
175
  version: '0'
177
176
  requirements: []
178
- rubygems_version: 3.5.14
179
- signing_key:
177
+ rubygems_version: 3.6.9
180
178
  specification_version: 4
181
179
  summary: Ruby SDK for AG-UI protocol
182
180
  test_files: []