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.
- checksums.yaml +4 -4
- data/lib/ag_ui_protocol/core/capabilities.rb +733 -0
- data/lib/ag_ui_protocol/core/events.rb +385 -28
- data/lib/ag_ui_protocol/core/types.rb +578 -80
- data/lib/ag_ui_protocol/encoder/event_encoder.rb +3 -4
- data/lib/ag_ui_protocol/util.rb +44 -1
- data/lib/ag_ui_protocol/version.rb +1 -1
- data/lib/ag_ui_protocol.rb +1 -0
- metadata +4 -6
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
require_relative "types"
|
|
6
|
+
|
|
7
|
+
module AgUiProtocol
|
|
8
|
+
module Core
|
|
9
|
+
# Agent capabilities define what an agent can do. They are declared by the agent
|
|
10
|
+
# implementation and communicated to the client during a run.
|
|
11
|
+
#
|
|
12
|
+
# All fields on `AgentCapabilities` and its sub-capability classes are optional — agents
|
|
13
|
+
# only declare what they support. (Nested helper types like `SubAgentInfo` may still have
|
|
14
|
+
# required identifier fields.) Omitted fields mean the capability is not declared
|
|
15
|
+
# (unknown), not that it's unsupported.
|
|
16
|
+
module Capabilities
|
|
17
|
+
# Describes a sub-agent that can be invoked by a parent agent.
|
|
18
|
+
class SubAgentInfo < AgUiProtocol::Core::Types::Model
|
|
19
|
+
sig { returns(String) }
|
|
20
|
+
attr_reader :name
|
|
21
|
+
|
|
22
|
+
sig { returns(T.nilable(String)) }
|
|
23
|
+
attr_reader :description
|
|
24
|
+
|
|
25
|
+
# @param name [String] Unique name or identifier of the sub-agent.
|
|
26
|
+
# @param description [String, nil] What this sub-agent specializes in. Helps clients build agent selection UIs.
|
|
27
|
+
sig do
|
|
28
|
+
params(
|
|
29
|
+
name: String,
|
|
30
|
+
description: T.nilable(String)
|
|
31
|
+
).void
|
|
32
|
+
end
|
|
33
|
+
def initialize(name:, description: nil)
|
|
34
|
+
@name = name
|
|
35
|
+
@description = description
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
39
|
+
def to_h
|
|
40
|
+
{
|
|
41
|
+
name: @name,
|
|
42
|
+
description: @description
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Basic metadata about the agent.
|
|
48
|
+
#
|
|
49
|
+
# Useful for discovery UIs, agent marketplaces, and debugging. Set these when you want
|
|
50
|
+
# clients to display agent information or when multiple agents are available and users
|
|
51
|
+
# need to pick one.
|
|
52
|
+
class IdentityCapabilities < AgUiProtocol::Core::Types::Model
|
|
53
|
+
sig { returns(T.nilable(String)) }
|
|
54
|
+
attr_reader :name
|
|
55
|
+
|
|
56
|
+
sig { returns(T.nilable(String)) }
|
|
57
|
+
attr_reader :type
|
|
58
|
+
|
|
59
|
+
sig { returns(T.nilable(String)) }
|
|
60
|
+
attr_reader :description
|
|
61
|
+
|
|
62
|
+
sig { returns(T.nilable(String)) }
|
|
63
|
+
attr_reader :version
|
|
64
|
+
|
|
65
|
+
sig { returns(T.nilable(String)) }
|
|
66
|
+
attr_reader :provider
|
|
67
|
+
|
|
68
|
+
sig { returns(T.nilable(String)) }
|
|
69
|
+
attr_reader :documentation_url
|
|
70
|
+
|
|
71
|
+
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
|
|
72
|
+
attr_reader :metadata
|
|
73
|
+
|
|
74
|
+
# @param name [String, nil] Human-readable name shown in UIs and agent selectors.
|
|
75
|
+
# @param type [String, nil] The framework or platform powering this agent (e.g., "langgraph", "mastra", "crewai").
|
|
76
|
+
# @param description [String, nil] What this agent does — helps users and routing logic decide when to use it.
|
|
77
|
+
# @param version [String, nil] Semantic version of the agent (e.g., "1.2.0"). Useful for compatibility checks.
|
|
78
|
+
# @param provider [String, nil] Organization or team that maintains this agent.
|
|
79
|
+
# @param documentation_url [String, nil] URL to the agent's documentation or homepage.
|
|
80
|
+
# @param metadata [Hash{String, Symbol => Object}, nil] Arbitrary key-value pairs for integration-specific identity info. String or Symbol keys are both accepted.
|
|
81
|
+
sig do
|
|
82
|
+
params(
|
|
83
|
+
name: T.nilable(String),
|
|
84
|
+
type: T.nilable(String),
|
|
85
|
+
description: T.nilable(String),
|
|
86
|
+
version: T.nilable(String),
|
|
87
|
+
provider: T.nilable(String),
|
|
88
|
+
documentation_url: T.nilable(String),
|
|
89
|
+
metadata: T.nilable(T::Hash[T.any(String, Symbol), T.untyped])
|
|
90
|
+
).void
|
|
91
|
+
end
|
|
92
|
+
def initialize(
|
|
93
|
+
name: nil, type: nil, description: nil, version: nil,
|
|
94
|
+
provider: nil, documentation_url: nil, metadata: nil
|
|
95
|
+
)
|
|
96
|
+
@name = name
|
|
97
|
+
@type = type
|
|
98
|
+
@description = description
|
|
99
|
+
@version = version
|
|
100
|
+
@provider = provider
|
|
101
|
+
@documentation_url = documentation_url
|
|
102
|
+
@metadata = metadata
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
106
|
+
def to_h
|
|
107
|
+
{
|
|
108
|
+
name: @name,
|
|
109
|
+
type: @type,
|
|
110
|
+
description: @description,
|
|
111
|
+
version: @version,
|
|
112
|
+
provider: @provider,
|
|
113
|
+
documentation_url: @documentation_url,
|
|
114
|
+
# `metadata` is arbitrary integration-specific identity info — preserve keys verbatim.
|
|
115
|
+
metadata: @metadata.nil? ? nil : AgUiProtocol::Util::Opaque.new(@metadata)
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Declares which transport mechanisms the agent supports.
|
|
121
|
+
#
|
|
122
|
+
# Clients use this to pick the best connection strategy. Only set flags to `true` for
|
|
123
|
+
# transports your agent actually handles — omit or set `false` for unsupported ones.
|
|
124
|
+
class TransportCapabilities < AgUiProtocol::Core::Types::Model
|
|
125
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
126
|
+
attr_reader :streaming
|
|
127
|
+
|
|
128
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
129
|
+
attr_reader :websocket
|
|
130
|
+
|
|
131
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
132
|
+
attr_reader :http_binary
|
|
133
|
+
|
|
134
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
135
|
+
attr_reader :push_notifications
|
|
136
|
+
|
|
137
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
138
|
+
attr_reader :resumable
|
|
139
|
+
|
|
140
|
+
# @param streaming [Boolean, nil] Set `true` if the agent streams responses via SSE. Most agents enable this.
|
|
141
|
+
# @param websocket [Boolean, nil] Set `true` if the agent accepts persistent WebSocket connections.
|
|
142
|
+
# @param http_binary [Boolean, nil] Set `true` if the agent supports the AG-UI binary protocol (protobuf over HTTP).
|
|
143
|
+
# @param push_notifications [Boolean, nil] Set `true` if the agent can send async updates via webhooks after a run finishes.
|
|
144
|
+
# @param resumable [Boolean, nil] Set `true` if the agent supports resuming interrupted streams via sequence numbers.
|
|
145
|
+
sig do
|
|
146
|
+
params(
|
|
147
|
+
streaming: T.nilable(T::Boolean),
|
|
148
|
+
websocket: T.nilable(T::Boolean),
|
|
149
|
+
http_binary: T.nilable(T::Boolean),
|
|
150
|
+
push_notifications: T.nilable(T::Boolean),
|
|
151
|
+
resumable: T.nilable(T::Boolean)
|
|
152
|
+
).void
|
|
153
|
+
end
|
|
154
|
+
def initialize(
|
|
155
|
+
streaming: nil, websocket: nil, http_binary: nil,
|
|
156
|
+
push_notifications: nil, resumable: nil
|
|
157
|
+
)
|
|
158
|
+
@streaming = streaming
|
|
159
|
+
@websocket = websocket
|
|
160
|
+
@http_binary = http_binary
|
|
161
|
+
@push_notifications = push_notifications
|
|
162
|
+
@resumable = resumable
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
166
|
+
def to_h
|
|
167
|
+
{
|
|
168
|
+
streaming: @streaming,
|
|
169
|
+
websocket: @websocket,
|
|
170
|
+
http_binary: @http_binary,
|
|
171
|
+
push_notifications: @push_notifications,
|
|
172
|
+
resumable: @resumable
|
|
173
|
+
}
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Tool calling capabilities.
|
|
178
|
+
#
|
|
179
|
+
# Distinguishes between tools the agent itself provides (listed in `items`) and tools
|
|
180
|
+
# the client passes at runtime via `RunAgentInput.tools`. Enable this when your agent
|
|
181
|
+
# can call functions, search the web, execute code, etc.
|
|
182
|
+
class ToolsCapabilities < AgUiProtocol::Core::Types::Model
|
|
183
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
184
|
+
attr_reader :supported
|
|
185
|
+
|
|
186
|
+
sig { returns(T.nilable(T::Array[AgUiProtocol::Core::Types::Tool])) }
|
|
187
|
+
attr_reader :items
|
|
188
|
+
|
|
189
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
190
|
+
attr_reader :parallel_calls
|
|
191
|
+
|
|
192
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
193
|
+
attr_reader :client_provided
|
|
194
|
+
|
|
195
|
+
# @param supported [Boolean, nil] Set `true` if the agent can make tool calls at all. Set `false` to explicitly signal tool calling is disabled even if items are present.
|
|
196
|
+
# @param items [Array<Tool>, nil] The tools this agent provides on its own (full JSON Schema definitions). These are distinct from client-provided tools passed in RunAgentInput.tools.
|
|
197
|
+
# @param parallel_calls [Boolean, nil] Set `true` if the agent can invoke multiple tools concurrently within a single step.
|
|
198
|
+
# @param client_provided [Boolean, nil] Set `true` if the agent accepts and uses tools provided by the client at runtime.
|
|
199
|
+
sig do
|
|
200
|
+
params(
|
|
201
|
+
supported: T.nilable(T::Boolean),
|
|
202
|
+
items: T.nilable(T::Array[AgUiProtocol::Core::Types::Tool]),
|
|
203
|
+
parallel_calls: T.nilable(T::Boolean),
|
|
204
|
+
client_provided: T.nilable(T::Boolean)
|
|
205
|
+
).void
|
|
206
|
+
end
|
|
207
|
+
def initialize(
|
|
208
|
+
supported: nil, items: nil, parallel_calls: nil, client_provided: nil
|
|
209
|
+
)
|
|
210
|
+
@supported = supported
|
|
211
|
+
@items = items
|
|
212
|
+
@parallel_calls = parallel_calls
|
|
213
|
+
@client_provided = client_provided
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
217
|
+
def to_h
|
|
218
|
+
{
|
|
219
|
+
supported: @supported,
|
|
220
|
+
items: @items,
|
|
221
|
+
parallel_calls: @parallel_calls,
|
|
222
|
+
client_provided: @client_provided
|
|
223
|
+
}
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Output format support.
|
|
228
|
+
#
|
|
229
|
+
# Enable `structured_output` when your agent can return responses conforming to a
|
|
230
|
+
# JSON schema, which is useful for programmatic consumption.
|
|
231
|
+
class OutputCapabilities < AgUiProtocol::Core::Types::Model
|
|
232
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
233
|
+
attr_reader :structured_output
|
|
234
|
+
|
|
235
|
+
sig { returns(T.nilable(T::Array[String])) }
|
|
236
|
+
attr_reader :supported_mime_types
|
|
237
|
+
|
|
238
|
+
# @param structured_output [Boolean, nil] Set `true` if the agent can produce structured JSON output matching a provided schema.
|
|
239
|
+
# @param supported_mime_types [Array<String>, nil] MIME types the agent can produce (e.g., ["text/plain", "application/json"]). Omit if the agent only produces plain text.
|
|
240
|
+
sig do
|
|
241
|
+
params(
|
|
242
|
+
structured_output: T.nilable(T::Boolean),
|
|
243
|
+
supported_mime_types: T.nilable(T::Array[String])
|
|
244
|
+
).void
|
|
245
|
+
end
|
|
246
|
+
def initialize(structured_output: nil, supported_mime_types: nil)
|
|
247
|
+
@structured_output = structured_output
|
|
248
|
+
@supported_mime_types = supported_mime_types
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
252
|
+
def to_h
|
|
253
|
+
{
|
|
254
|
+
structured_output: @structured_output,
|
|
255
|
+
supported_mime_types: @supported_mime_types
|
|
256
|
+
}
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# State and memory management capabilities.
|
|
261
|
+
#
|
|
262
|
+
# These tell the client how the agent handles shared state and whether conversation
|
|
263
|
+
# context persists across runs.
|
|
264
|
+
class StateCapabilities < AgUiProtocol::Core::Types::Model
|
|
265
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
266
|
+
attr_reader :snapshots
|
|
267
|
+
|
|
268
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
269
|
+
attr_reader :deltas
|
|
270
|
+
|
|
271
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
272
|
+
attr_reader :memory
|
|
273
|
+
|
|
274
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
275
|
+
attr_reader :persistent_state
|
|
276
|
+
|
|
277
|
+
# @param snapshots [Boolean, nil] Set `true` if the agent emits STATE_SNAPSHOT events (full state replacement).
|
|
278
|
+
# @param deltas [Boolean, nil] Set `true` if the agent emits STATE_DELTA events (JSON Patch incremental updates).
|
|
279
|
+
# @param memory [Boolean, nil] Set `true` if the agent has long-term memory beyond the current thread (e.g., vector store, knowledge base, or cross-session recall).
|
|
280
|
+
# @param persistent_state [Boolean, nil] Set `true` if state is preserved across multiple runs within the same thread. When `false`, state resets on each run.
|
|
281
|
+
sig do
|
|
282
|
+
params(
|
|
283
|
+
snapshots: T.nilable(T::Boolean),
|
|
284
|
+
deltas: T.nilable(T::Boolean),
|
|
285
|
+
memory: T.nilable(T::Boolean),
|
|
286
|
+
persistent_state: T.nilable(T::Boolean)
|
|
287
|
+
).void
|
|
288
|
+
end
|
|
289
|
+
def initialize(snapshots: nil, deltas: nil, memory: nil, persistent_state: nil)
|
|
290
|
+
@snapshots = snapshots
|
|
291
|
+
@deltas = deltas
|
|
292
|
+
@memory = memory
|
|
293
|
+
@persistent_state = persistent_state
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
297
|
+
def to_h
|
|
298
|
+
{
|
|
299
|
+
snapshots: @snapshots,
|
|
300
|
+
deltas: @deltas,
|
|
301
|
+
memory: @memory,
|
|
302
|
+
persistent_state: @persistent_state
|
|
303
|
+
}
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Multi-agent coordination capabilities.
|
|
308
|
+
#
|
|
309
|
+
# Enable these when your agent can orchestrate or hand off work to other agents.
|
|
310
|
+
class MultiAgentCapabilities < AgUiProtocol::Core::Types::Model
|
|
311
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
312
|
+
attr_reader :supported
|
|
313
|
+
|
|
314
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
315
|
+
attr_reader :delegation
|
|
316
|
+
|
|
317
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
318
|
+
attr_reader :handoffs
|
|
319
|
+
|
|
320
|
+
sig { returns(T.nilable(T::Array[SubAgentInfo])) }
|
|
321
|
+
attr_reader :sub_agents
|
|
322
|
+
|
|
323
|
+
# @param supported [Boolean, nil] Set `true` if the agent participates in any form of multi-agent coordination.
|
|
324
|
+
# @param delegation [Boolean, nil] Set `true` if the agent can delegate subtasks to other agents while retaining control.
|
|
325
|
+
# @param handoffs [Boolean, nil] Set `true` if the agent can transfer the conversation entirely to another agent.
|
|
326
|
+
# @param sub_agents [Array<SubAgentInfo>, nil] List of sub-agents this agent can invoke. Helps clients build agent selection UIs.
|
|
327
|
+
sig do
|
|
328
|
+
params(
|
|
329
|
+
supported: T.nilable(T::Boolean),
|
|
330
|
+
delegation: T.nilable(T::Boolean),
|
|
331
|
+
handoffs: T.nilable(T::Boolean),
|
|
332
|
+
sub_agents: T.nilable(T::Array[SubAgentInfo])
|
|
333
|
+
).void
|
|
334
|
+
end
|
|
335
|
+
def initialize(
|
|
336
|
+
supported: nil, delegation: nil, handoffs: nil, sub_agents: nil
|
|
337
|
+
)
|
|
338
|
+
@supported = supported
|
|
339
|
+
@delegation = delegation
|
|
340
|
+
@handoffs = handoffs
|
|
341
|
+
@sub_agents = sub_agents
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
345
|
+
def to_h
|
|
346
|
+
{
|
|
347
|
+
supported: @supported,
|
|
348
|
+
delegation: @delegation,
|
|
349
|
+
handoffs: @handoffs,
|
|
350
|
+
sub_agents: @sub_agents
|
|
351
|
+
}
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
# Reasoning and thinking capabilities.
|
|
356
|
+
#
|
|
357
|
+
# Enable these when your agent exposes its internal thought process (e.g.,
|
|
358
|
+
# chain-of-thought, extended thinking).
|
|
359
|
+
class ReasoningCapabilities < AgUiProtocol::Core::Types::Model
|
|
360
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
361
|
+
attr_reader :supported
|
|
362
|
+
|
|
363
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
364
|
+
attr_reader :streaming
|
|
365
|
+
|
|
366
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
367
|
+
attr_reader :encrypted
|
|
368
|
+
|
|
369
|
+
# @param supported [Boolean, nil] Set `true` if the agent produces reasoning/thinking tokens visible to the client.
|
|
370
|
+
# @param streaming [Boolean, nil] Set `true` if reasoning tokens are streamed incrementally (vs. returned all at once).
|
|
371
|
+
# @param encrypted [Boolean, nil] Set `true` if reasoning content is encrypted (zero-data-retention mode). Clients should expect opaque `encrypted_value` fields instead of readable content.
|
|
372
|
+
sig do
|
|
373
|
+
params(
|
|
374
|
+
supported: T.nilable(T::Boolean),
|
|
375
|
+
streaming: T.nilable(T::Boolean),
|
|
376
|
+
encrypted: T.nilable(T::Boolean)
|
|
377
|
+
).void
|
|
378
|
+
end
|
|
379
|
+
def initialize(supported: nil, streaming: nil, encrypted: nil)
|
|
380
|
+
@supported = supported
|
|
381
|
+
@streaming = streaming
|
|
382
|
+
@encrypted = encrypted
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
386
|
+
def to_h
|
|
387
|
+
{
|
|
388
|
+
supported: @supported,
|
|
389
|
+
streaming: @streaming,
|
|
390
|
+
encrypted: @encrypted
|
|
391
|
+
}
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# Modalities the agent can accept as input.
|
|
396
|
+
#
|
|
397
|
+
# Clients use this to show/hide file upload buttons, audio recorders, image pickers, etc.
|
|
398
|
+
class MultimodalInputCapabilities < AgUiProtocol::Core::Types::Model
|
|
399
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
400
|
+
attr_reader :image
|
|
401
|
+
|
|
402
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
403
|
+
attr_reader :audio
|
|
404
|
+
|
|
405
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
406
|
+
attr_reader :video
|
|
407
|
+
|
|
408
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
409
|
+
attr_reader :pdf
|
|
410
|
+
|
|
411
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
412
|
+
attr_reader :file
|
|
413
|
+
|
|
414
|
+
# @param image [Boolean, nil] Set `true` if the agent can process image inputs (e.g., screenshots, photos).
|
|
415
|
+
# @param audio [Boolean, nil] Set `true` if the agent can process audio inputs (speech, recordings).
|
|
416
|
+
# @param video [Boolean, nil] Set `true` if the agent can process video inputs.
|
|
417
|
+
# @param pdf [Boolean, nil] Set `true` if the agent can process PDF documents.
|
|
418
|
+
# @param file [Boolean, nil] Set `true` if the agent can process arbitrary file uploads.
|
|
419
|
+
sig do
|
|
420
|
+
params(
|
|
421
|
+
image: T.nilable(T::Boolean),
|
|
422
|
+
audio: T.nilable(T::Boolean),
|
|
423
|
+
video: T.nilable(T::Boolean),
|
|
424
|
+
pdf: T.nilable(T::Boolean),
|
|
425
|
+
file: T.nilable(T::Boolean)
|
|
426
|
+
).void
|
|
427
|
+
end
|
|
428
|
+
def initialize(image: nil, audio: nil, video: nil, pdf: nil, file: nil)
|
|
429
|
+
@image = image
|
|
430
|
+
@audio = audio
|
|
431
|
+
@video = video
|
|
432
|
+
@pdf = pdf
|
|
433
|
+
@file = file
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
437
|
+
def to_h
|
|
438
|
+
{
|
|
439
|
+
image: @image,
|
|
440
|
+
audio: @audio,
|
|
441
|
+
video: @video,
|
|
442
|
+
pdf: @pdf,
|
|
443
|
+
file: @file
|
|
444
|
+
}
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Modalities the agent can produce as output.
|
|
449
|
+
#
|
|
450
|
+
# Clients use this to anticipate rich content in the agent's response.
|
|
451
|
+
class MultimodalOutputCapabilities < AgUiProtocol::Core::Types::Model
|
|
452
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
453
|
+
attr_reader :image
|
|
454
|
+
|
|
455
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
456
|
+
attr_reader :audio
|
|
457
|
+
|
|
458
|
+
# @param image [Boolean, nil] Set `true` if the agent can generate images as part of its response.
|
|
459
|
+
# @param audio [Boolean, nil] Set `true` if the agent can produce audio output (text-to-speech, audio files).
|
|
460
|
+
sig do
|
|
461
|
+
params(
|
|
462
|
+
image: T.nilable(T::Boolean),
|
|
463
|
+
audio: T.nilable(T::Boolean)
|
|
464
|
+
).void
|
|
465
|
+
end
|
|
466
|
+
def initialize(image: nil, audio: nil)
|
|
467
|
+
@image = image
|
|
468
|
+
@audio = audio
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
472
|
+
def to_h
|
|
473
|
+
{
|
|
474
|
+
image: @image,
|
|
475
|
+
audio: @audio
|
|
476
|
+
}
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# Multimodal input and output support.
|
|
481
|
+
#
|
|
482
|
+
# Organized into `input` and `output` sub-objects so clients can independently query
|
|
483
|
+
# what the agent accepts versus what it produces.
|
|
484
|
+
class MultimodalCapabilities < AgUiProtocol::Core::Types::Model
|
|
485
|
+
sig { returns(T.nilable(MultimodalInputCapabilities)) }
|
|
486
|
+
attr_reader :input
|
|
487
|
+
|
|
488
|
+
sig { returns(T.nilable(MultimodalOutputCapabilities)) }
|
|
489
|
+
attr_reader :output
|
|
490
|
+
|
|
491
|
+
# @param input [MultimodalInputCapabilities, nil] Modalities the agent can accept as input (images, audio, video, PDFs, files).
|
|
492
|
+
# @param output [MultimodalOutputCapabilities, nil] Modalities the agent can produce as output (images, audio).
|
|
493
|
+
sig do
|
|
494
|
+
params(
|
|
495
|
+
input: T.nilable(MultimodalInputCapabilities),
|
|
496
|
+
output: T.nilable(MultimodalOutputCapabilities)
|
|
497
|
+
).void
|
|
498
|
+
end
|
|
499
|
+
def initialize(input: nil, output: nil)
|
|
500
|
+
@input = input
|
|
501
|
+
@output = output
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
505
|
+
def to_h
|
|
506
|
+
{
|
|
507
|
+
input: @input,
|
|
508
|
+
output: @output
|
|
509
|
+
}
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# Execution control and limits.
|
|
514
|
+
#
|
|
515
|
+
# Declare these so clients can set expectations about how long or how many steps an
|
|
516
|
+
# agent run might take.
|
|
517
|
+
class ExecutionCapabilities < AgUiProtocol::Core::Types::Model
|
|
518
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
519
|
+
attr_reader :code_execution
|
|
520
|
+
|
|
521
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
522
|
+
attr_reader :sandboxed
|
|
523
|
+
|
|
524
|
+
sig { returns(T.nilable(Integer)) }
|
|
525
|
+
attr_reader :max_iterations
|
|
526
|
+
|
|
527
|
+
sig { returns(T.nilable(Integer)) }
|
|
528
|
+
attr_reader :max_execution_time
|
|
529
|
+
|
|
530
|
+
# @param code_execution [Boolean, nil] Set `true` if the agent can execute code (e.g., Python, JavaScript) during a run.
|
|
531
|
+
# @param sandboxed [Boolean, nil] Set `true` if code execution happens in a sandboxed/isolated environment. Only meaningful when `code_execution` is `true`.
|
|
532
|
+
# @param max_iterations [Integer, nil] Maximum number of tool-call/reasoning iterations the agent will perform per run. Helps clients display progress or set timeout expectations.
|
|
533
|
+
# @param max_execution_time [Integer, nil] Maximum wall-clock time (in milliseconds) the agent will run before timing out.
|
|
534
|
+
sig do
|
|
535
|
+
params(
|
|
536
|
+
code_execution: T.nilable(T::Boolean),
|
|
537
|
+
sandboxed: T.nilable(T::Boolean),
|
|
538
|
+
max_iterations: T.nilable(Integer),
|
|
539
|
+
max_execution_time: T.nilable(Integer)
|
|
540
|
+
).void
|
|
541
|
+
end
|
|
542
|
+
def initialize(
|
|
543
|
+
code_execution: nil, sandboxed: nil,
|
|
544
|
+
max_iterations: nil, max_execution_time: nil
|
|
545
|
+
)
|
|
546
|
+
@code_execution = code_execution
|
|
547
|
+
@sandboxed = sandboxed
|
|
548
|
+
@max_iterations = max_iterations
|
|
549
|
+
@max_execution_time = max_execution_time
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
553
|
+
def to_h
|
|
554
|
+
{
|
|
555
|
+
code_execution: @code_execution,
|
|
556
|
+
sandboxed: @sandboxed,
|
|
557
|
+
max_iterations: @max_iterations,
|
|
558
|
+
max_execution_time: @max_execution_time
|
|
559
|
+
}
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
# Human-in-the-loop interaction support.
|
|
564
|
+
#
|
|
565
|
+
# Enable these when your agent can pause execution to request human input, approval,
|
|
566
|
+
# or feedback before continuing.
|
|
567
|
+
class HumanInTheLoopCapabilities < AgUiProtocol::Core::Types::Model
|
|
568
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
569
|
+
attr_reader :supported
|
|
570
|
+
|
|
571
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
572
|
+
attr_reader :approvals
|
|
573
|
+
|
|
574
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
575
|
+
attr_reader :interventions
|
|
576
|
+
|
|
577
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
578
|
+
attr_reader :feedback
|
|
579
|
+
|
|
580
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
581
|
+
attr_reader :interrupts
|
|
582
|
+
|
|
583
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
584
|
+
attr_reader :approve_with_edits
|
|
585
|
+
|
|
586
|
+
# @param supported [Boolean, nil] Set `true` if the agent supports any form of human-in-the-loop interaction.
|
|
587
|
+
# @param approvals [Boolean, nil] Set `true` if the agent can pause and request explicit approval before performing sensitive actions (e.g., sending emails, deleting data).
|
|
588
|
+
# @param interventions [Boolean, nil] Set `true` if the agent allows humans to intervene and modify its plan mid-execution.
|
|
589
|
+
# @param feedback [Boolean, nil] Set `true` if the agent can incorporate user feedback (thumbs up/down, corrections) to improve its behavior within the current session.
|
|
590
|
+
# @param interrupts [Boolean, nil] Set `true` if the agent participates in the AG-UI interrupt protocol (emits RUN_FINISHED with interrupt outcome, accepts resume[]).
|
|
591
|
+
# @param approve_with_edits [Boolean, nil] Set `true` if tool-call interrupts accept editedArgs in the resume payload. Only meaningful when interrupts is true.
|
|
592
|
+
sig do
|
|
593
|
+
params(
|
|
594
|
+
supported: T.nilable(T::Boolean),
|
|
595
|
+
approvals: T.nilable(T::Boolean),
|
|
596
|
+
interventions: T.nilable(T::Boolean),
|
|
597
|
+
feedback: T.nilable(T::Boolean),
|
|
598
|
+
interrupts: T.nilable(T::Boolean),
|
|
599
|
+
approve_with_edits: T.nilable(T::Boolean)
|
|
600
|
+
).void
|
|
601
|
+
end
|
|
602
|
+
def initialize(
|
|
603
|
+
supported: nil, approvals: nil, interventions: nil,
|
|
604
|
+
feedback: nil, interrupts: nil, approve_with_edits: nil
|
|
605
|
+
)
|
|
606
|
+
@supported = supported
|
|
607
|
+
@approvals = approvals
|
|
608
|
+
@interventions = interventions
|
|
609
|
+
@feedback = feedback
|
|
610
|
+
@interrupts = interrupts
|
|
611
|
+
@approve_with_edits = approve_with_edits
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
615
|
+
def to_h
|
|
616
|
+
{
|
|
617
|
+
supported: @supported,
|
|
618
|
+
approvals: @approvals,
|
|
619
|
+
interventions: @interventions,
|
|
620
|
+
feedback: @feedback,
|
|
621
|
+
interrupts: @interrupts,
|
|
622
|
+
approve_with_edits: @approve_with_edits
|
|
623
|
+
}
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
# A categorized snapshot of an agent's current capabilities.
|
|
628
|
+
#
|
|
629
|
+
# All fields are optional — agents only declare what they support. Omitted fields mean
|
|
630
|
+
# the capability is not declared (unknown), not that it's unsupported.
|
|
631
|
+
#
|
|
632
|
+
# The `custom` field is an escape hatch for integration-specific capabilities that
|
|
633
|
+
# don't fit into the standard categories.
|
|
634
|
+
class AgentCapabilities < AgUiProtocol::Core::Types::Model
|
|
635
|
+
sig { returns(T.nilable(IdentityCapabilities)) }
|
|
636
|
+
attr_reader :identity
|
|
637
|
+
|
|
638
|
+
sig { returns(T.nilable(TransportCapabilities)) }
|
|
639
|
+
attr_reader :transport
|
|
640
|
+
|
|
641
|
+
sig { returns(T.nilable(ToolsCapabilities)) }
|
|
642
|
+
attr_reader :tools
|
|
643
|
+
|
|
644
|
+
sig { returns(T.nilable(OutputCapabilities)) }
|
|
645
|
+
attr_reader :output
|
|
646
|
+
|
|
647
|
+
sig { returns(T.nilable(StateCapabilities)) }
|
|
648
|
+
attr_reader :state
|
|
649
|
+
|
|
650
|
+
sig { returns(T.nilable(MultiAgentCapabilities)) }
|
|
651
|
+
attr_reader :multi_agent
|
|
652
|
+
|
|
653
|
+
sig { returns(T.nilable(ReasoningCapabilities)) }
|
|
654
|
+
attr_reader :reasoning
|
|
655
|
+
|
|
656
|
+
sig { returns(T.nilable(MultimodalCapabilities)) }
|
|
657
|
+
attr_reader :multimodal
|
|
658
|
+
|
|
659
|
+
sig { returns(T.nilable(ExecutionCapabilities)) }
|
|
660
|
+
attr_reader :execution
|
|
661
|
+
|
|
662
|
+
sig { returns(T.nilable(HumanInTheLoopCapabilities)) }
|
|
663
|
+
attr_reader :human_in_the_loop
|
|
664
|
+
|
|
665
|
+
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
|
|
666
|
+
attr_reader :custom
|
|
667
|
+
|
|
668
|
+
# @param identity [IdentityCapabilities, nil] Agent identity and metadata.
|
|
669
|
+
# @param transport [TransportCapabilities, nil] Supported transport mechanisms (SSE, WebSocket, binary, etc.).
|
|
670
|
+
# @param tools [ToolsCapabilities, nil] Tools the agent provides and tool calling configuration.
|
|
671
|
+
# @param output [OutputCapabilities, nil] Output format support (structured output, MIME types).
|
|
672
|
+
# @param state [StateCapabilities, nil] State and memory management (snapshots, deltas, persistence).
|
|
673
|
+
# @param multi_agent [MultiAgentCapabilities, nil] Multi-agent coordination (delegation, handoffs, sub-agents).
|
|
674
|
+
# @param reasoning [ReasoningCapabilities, nil] Reasoning and thinking support (chain-of-thought, encrypted thinking).
|
|
675
|
+
# @param multimodal [MultimodalCapabilities, nil] Multimodal input/output support (images, audio, video, files).
|
|
676
|
+
# @param execution [ExecutionCapabilities, nil] Execution control and limits (code execution, timeouts, iteration caps).
|
|
677
|
+
# @param human_in_the_loop [HumanInTheLoopCapabilities, nil] Human-in-the-loop support (approvals, interventions, feedback).
|
|
678
|
+
# @param custom [Hash{String, Symbol => Object}, nil] Integration-specific capabilities not covered by the standard categories. String or Symbol keys are both accepted.
|
|
679
|
+
sig do
|
|
680
|
+
params(
|
|
681
|
+
identity: T.nilable(IdentityCapabilities),
|
|
682
|
+
transport: T.nilable(TransportCapabilities),
|
|
683
|
+
tools: T.nilable(ToolsCapabilities),
|
|
684
|
+
output: T.nilable(OutputCapabilities),
|
|
685
|
+
state: T.nilable(StateCapabilities),
|
|
686
|
+
multi_agent: T.nilable(MultiAgentCapabilities),
|
|
687
|
+
reasoning: T.nilable(ReasoningCapabilities),
|
|
688
|
+
multimodal: T.nilable(MultimodalCapabilities),
|
|
689
|
+
execution: T.nilable(ExecutionCapabilities),
|
|
690
|
+
human_in_the_loop: T.nilable(HumanInTheLoopCapabilities),
|
|
691
|
+
custom: T.nilable(T::Hash[T.any(String, Symbol), T.untyped])
|
|
692
|
+
).void
|
|
693
|
+
end
|
|
694
|
+
def initialize(
|
|
695
|
+
identity: nil, transport: nil, tools: nil, output: nil,
|
|
696
|
+
state: nil, multi_agent: nil, reasoning: nil, multimodal: nil,
|
|
697
|
+
execution: nil, human_in_the_loop: nil, custom: nil
|
|
698
|
+
)
|
|
699
|
+
@identity = identity
|
|
700
|
+
@transport = transport
|
|
701
|
+
@tools = tools
|
|
702
|
+
@output = output
|
|
703
|
+
@state = state
|
|
704
|
+
@multi_agent = multi_agent
|
|
705
|
+
@reasoning = reasoning
|
|
706
|
+
@multimodal = multimodal
|
|
707
|
+
@execution = execution
|
|
708
|
+
@human_in_the_loop = human_in_the_loop
|
|
709
|
+
@custom = custom
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
713
|
+
def to_h
|
|
714
|
+
{
|
|
715
|
+
identity: @identity,
|
|
716
|
+
transport: @transport,
|
|
717
|
+
tools: @tools,
|
|
718
|
+
output: @output,
|
|
719
|
+
state: @state,
|
|
720
|
+
multi_agent: @multi_agent,
|
|
721
|
+
reasoning: @reasoning,
|
|
722
|
+
multimodal: @multimodal,
|
|
723
|
+
execution: @execution,
|
|
724
|
+
human_in_the_loop: @human_in_the_loop,
|
|
725
|
+
# `custom` is the explicit escape hatch for integration-specific
|
|
726
|
+
# capabilities — preserve keys verbatim.
|
|
727
|
+
custom: @custom.nil? ? nil : AgUiProtocol::Util::Opaque.new(@custom)
|
|
728
|
+
}
|
|
729
|
+
end
|
|
730
|
+
end
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
end
|