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.
@@ -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