ag-ui-protocol 0.1.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.
- checksums.yaml +7 -0
- data/lib/ag_ui_protocol/core/events.rb +1024 -0
- data/lib/ag_ui_protocol/core/types.rb +717 -0
- data/lib/ag_ui_protocol/encoder/event_encoder.rb +83 -0
- data/lib/ag_ui_protocol/util.rb +76 -0
- data/lib/ag_ui_protocol/version.rb +6 -0
- data/lib/ag_ui_protocol.rb +15 -0
- metadata +181 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
require "sorbet-runtime"
|
|
6
|
+
|
|
7
|
+
module AgUiProtocol
|
|
8
|
+
# The Agent User Interaction Protocol uses a streaming approach to send events
|
|
9
|
+
# from agents to clients. The `EventEncoder` class provides the functionality to
|
|
10
|
+
# encode events into a format that can be sent over HTTP.
|
|
11
|
+
module Encoder
|
|
12
|
+
# Media type for AGUI events
|
|
13
|
+
AGUI_MEDIA_TYPE = "application/vnd.ag-ui.event+proto"
|
|
14
|
+
|
|
15
|
+
# The `EventEncoder` class is responsible for encoding `BaseEvent` objects into
|
|
16
|
+
# string representations that can be transmitted to clients.
|
|
17
|
+
#
|
|
18
|
+
# ```ruby
|
|
19
|
+
#
|
|
20
|
+
# require "ag_ui_protocol"
|
|
21
|
+
#
|
|
22
|
+
# encoder = AgUiProtocol::EventEncoder.new
|
|
23
|
+
#
|
|
24
|
+
# event = AgUiProtocol::Core::Events::TextMessageContentEvent.new(
|
|
25
|
+
# message_id: "msg_123",
|
|
26
|
+
# delta: "Hello, world!"
|
|
27
|
+
# )
|
|
28
|
+
#
|
|
29
|
+
# encoded = encoder.encode(event)
|
|
30
|
+
#
|
|
31
|
+
# ```
|
|
32
|
+
#
|
|
33
|
+
# ### Usage
|
|
34
|
+
#
|
|
35
|
+
# The `EventEncoder` is typically used in HTTP handlers to convert event objects
|
|
36
|
+
# into a stream of data. The current implementation encodes events as Server-Sent
|
|
37
|
+
# Events (SSE), which can be consumed by clients using the EventSource API.
|
|
38
|
+
#
|
|
39
|
+
# ### Implementation Details
|
|
40
|
+
#
|
|
41
|
+
# Internally, the encoder converts events to JSON and formats them as Server-Sent
|
|
42
|
+
# Events with the following structure:
|
|
43
|
+
#
|
|
44
|
+
# ```
|
|
45
|
+
# data: {json-serialized event}\n\n
|
|
46
|
+
# ```
|
|
47
|
+
#
|
|
48
|
+
# This format allows clients to receive a continuous stream of events and process
|
|
49
|
+
# them as they arrive.
|
|
50
|
+
#
|
|
51
|
+
class EventEncoder
|
|
52
|
+
extend T::Sig
|
|
53
|
+
|
|
54
|
+
# Creates a new encoder instance.
|
|
55
|
+
#
|
|
56
|
+
# @param accept [String, nil] Media type of the request
|
|
57
|
+
# @return [void]
|
|
58
|
+
sig { params(accept: T.nilable(String)).void }
|
|
59
|
+
def initialize(accept: nil)
|
|
60
|
+
@accept = accept
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns the content type of the encoder.
|
|
64
|
+
#
|
|
65
|
+
# @return [String] The content type of the encoder
|
|
66
|
+
sig { returns(String) }
|
|
67
|
+
def content_type
|
|
68
|
+
@accept || "text/event-stream"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Encodes an event into a string representation.
|
|
72
|
+
#
|
|
73
|
+
# @param event [Object] The event to encode
|
|
74
|
+
# @return [String] A string representation of the event in SSE format.
|
|
75
|
+
sig { params(event: AgUiProtocol::Core::Types::Model).returns(String) }
|
|
76
|
+
def encode(event)
|
|
77
|
+
payload = event.as_json
|
|
78
|
+
|
|
79
|
+
"data: #{JSON.generate(payload)}\n\n"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
module AgUiProtocol
|
|
8
|
+
# Utility methods for encoding events.
|
|
9
|
+
module Util
|
|
10
|
+
extend T::Sig
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
# @param value [Object]
|
|
14
|
+
# @return [Object]
|
|
15
|
+
sig { params(value: T.untyped).returns(T.untyped) }
|
|
16
|
+
def normalize_value(value)
|
|
17
|
+
if value.is_a?(AgUiProtocol::Core::Types::Model)
|
|
18
|
+
value.to_h
|
|
19
|
+
else
|
|
20
|
+
value
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param key [Object]
|
|
25
|
+
# @return [String]
|
|
26
|
+
sig { params(key: T.untyped).returns(String) }
|
|
27
|
+
def camelize_key(key)
|
|
28
|
+
str = key.to_s
|
|
29
|
+
parts = str.split("_")
|
|
30
|
+
return str if parts.length <= 1
|
|
31
|
+
|
|
32
|
+
parts[0] + parts[1..].map { |p| p.empty? ? "" : (p[0].upcase + p[1..]) }.join
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @param value [Object]
|
|
36
|
+
# @return [Object]
|
|
37
|
+
sig { params(value: T.untyped).returns(T.untyped) }
|
|
38
|
+
def deep_compact(value)
|
|
39
|
+
value = normalize_value(value)
|
|
40
|
+
case value
|
|
41
|
+
when Hash
|
|
42
|
+
value.transform_values { |v| deep_compact(v) unless v.nil? }.tap(&:compact!)
|
|
43
|
+
when Array
|
|
44
|
+
tmp1 = value.map { |v| deep_compact(v) }
|
|
45
|
+
tmp1.reject!(&:nil?)
|
|
46
|
+
tmp1
|
|
47
|
+
else
|
|
48
|
+
value
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @param value [Object]
|
|
53
|
+
# @return [Object]
|
|
54
|
+
sig { params(value: T.untyped).returns(T.untyped) }
|
|
55
|
+
def deep_transform_keys_to_camel(value)
|
|
56
|
+
value = normalize_value(value)
|
|
57
|
+
case value
|
|
58
|
+
when Hash
|
|
59
|
+
value.each_with_object({}) do |(k, v), acc|
|
|
60
|
+
acc[camelize_key(k)] = deep_transform_keys_to_camel(v)
|
|
61
|
+
end
|
|
62
|
+
when Array
|
|
63
|
+
value.map { |v| deep_transform_keys_to_camel(v) }
|
|
64
|
+
else
|
|
65
|
+
value
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @param value [Object]
|
|
70
|
+
# @return [String]
|
|
71
|
+
sig { params(value: T.untyped).returns(String) }
|
|
72
|
+
def dump_json(value)
|
|
73
|
+
JSON.generate(value)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require_relative "ag_ui_protocol/version"
|
|
7
|
+
require_relative "ag_ui_protocol/util"
|
|
8
|
+
require_relative "ag_ui_protocol/core/types"
|
|
9
|
+
require_relative "ag_ui_protocol/core/events"
|
|
10
|
+
require_relative "ag_ui_protocol/encoder/event_encoder"
|
|
11
|
+
|
|
12
|
+
module AgUiProtocol
|
|
13
|
+
AGUI_MEDIA_TYPE = Encoder::AGUI_MEDIA_TYPE
|
|
14
|
+
EventEncoder = Encoder::EventEncoder
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ag-ui-protocol
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Buk
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-12-24 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: json
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: sorbet-runtime
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.5.12392
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 0.5.12392
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: minitest
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '5.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '5.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: minitest-reporters
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.7.1
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 1.7.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: shoulda-context
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '2.0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '2.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rake
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: sorbet
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 0.5.12392
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 0.5.12392
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: yard
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0.9'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0.9'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: yard-markdown
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.3'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.3'
|
|
139
|
+
description: Ruby SDK for AG-UI protocol - standardizing agent-user interactions through
|
|
140
|
+
event-based communication
|
|
141
|
+
email:
|
|
142
|
+
- contacto@buk.cl
|
|
143
|
+
executables: []
|
|
144
|
+
extensions: []
|
|
145
|
+
extra_rdoc_files: []
|
|
146
|
+
files:
|
|
147
|
+
- lib/ag_ui_protocol.rb
|
|
148
|
+
- lib/ag_ui_protocol/core/events.rb
|
|
149
|
+
- lib/ag_ui_protocol/core/types.rb
|
|
150
|
+
- lib/ag_ui_protocol/encoder/event_encoder.rb
|
|
151
|
+
- lib/ag_ui_protocol/util.rb
|
|
152
|
+
- lib/ag_ui_protocol/version.rb
|
|
153
|
+
homepage: https://docs.ag-ui.com/introduction
|
|
154
|
+
licenses:
|
|
155
|
+
- MIT
|
|
156
|
+
metadata:
|
|
157
|
+
rubygems_mfa_required: 'true'
|
|
158
|
+
source_code_uri: https://github.com/ag-ui-protocol/ag-ui
|
|
159
|
+
documentation_uri: https://github.com/ag-ui-protocol/ag-ui/tree/main/docs/sdk/ruby
|
|
160
|
+
changelog_uri: https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/ruby/CHANGELOG.md
|
|
161
|
+
homepage_uri: https://docs.ag-ui.com/introduction
|
|
162
|
+
post_install_message:
|
|
163
|
+
rdoc_options: []
|
|
164
|
+
require_paths:
|
|
165
|
+
- lib
|
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
|
+
requirements:
|
|
168
|
+
- - ">="
|
|
169
|
+
- !ruby/object:Gem::Version
|
|
170
|
+
version: '3.0'
|
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
|
+
requirements:
|
|
173
|
+
- - ">="
|
|
174
|
+
- !ruby/object:Gem::Version
|
|
175
|
+
version: '0'
|
|
176
|
+
requirements: []
|
|
177
|
+
rubygems_version: 3.5.14
|
|
178
|
+
signing_key:
|
|
179
|
+
specification_version: 4
|
|
180
|
+
summary: Ruby SDK for AG-UI protocol
|
|
181
|
+
test_files: []
|