acp-sdk 0.10.0 → 0.11.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/CHANGELOG.md +21 -0
- data/README.md +15 -5
- data/lib/acp/agent_connection/client.rb +7 -19
- data/lib/acp/agent_connection/optional_method/spec.rb +42 -0
- data/lib/acp/agent_connection/optional_method.rb +36 -0
- data/lib/acp/agent_connection.rb +17 -40
- data/lib/acp/agent_process.rb +0 -13
- data/lib/acp/client_connection/streams.rb +183 -0
- data/lib/acp/client_connection.rb +227 -384
- data/lib/acp/protocol.rb +33 -0
- data/lib/acp/request_error.rb +7 -17
- data/lib/acp/transport/cancellation.rb +0 -7
- data/lib/acp/transport/reply.rb +0 -2
- data/lib/acp/transport/stderr_logger.rb +1 -2
- data/lib/acp/transport/stdio.rb +16 -22
- data/lib/acp/types/audio_content.rb +3 -46
- data/lib/acp/types/auth_method_terminal.rb +3 -59
- data/lib/acp/types/available_commands_update.rb +3 -32
- data/lib/acp/types/boolean_property_schema.rb +3 -41
- data/lib/acp/types/check.rb +210 -0
- data/lib/acp/types/config_option_update.rb +3 -32
- data/lib/acp/types/content.rb +3 -29
- data/lib/acp/types/{elicitation_url_mode → create_elicitation_request/mode/form}/scope.rb +1 -1
- data/lib/acp/types/create_elicitation_request/mode/form.rb +3 -3
- data/lib/acp/types/{elicitation_form_mode → create_elicitation_request/mode/url}/scope.rb +1 -1
- data/lib/acp/types/create_elicitation_request/mode/url.rb +3 -3
- data/lib/acp/types/current_mode_update.rb +3 -29
- data/lib/acp/types/diff.rb +3 -41
- data/lib/acp/types/elicitation_accept_action.rb +3 -26
- data/lib/acp/types/elicitation_form_mode.rb +3 -33
- data/lib/acp/types/elicitation_url_mode.rb +3 -35
- data/lib/acp/types/embedded_resource.rb +3 -44
- data/lib/acp/types/image_content.rb +3 -58
- data/lib/acp/types/integer_property_schema.rb +3 -60
- data/lib/acp/types/mcp_server_http.rb +3 -44
- data/lib/acp/types/mcp_server_sse.rb +3 -44
- data/lib/acp/types/multi_select_property_schema.rb +3 -70
- data/lib/acp/types/number_property_schema.rb +3 -60
- data/lib/acp/types/parse_error.rb +37 -0
- data/lib/acp/types/plan.rb +3 -29
- data/lib/acp/types/resource_link.rb +3 -79
- data/lib/acp/types/selected_permission_outcome.rb +3 -26
- data/lib/acp/types/session_config_boolean.rb +3 -21
- data/lib/acp/types/session_config_select.rb +3 -33
- data/lib/acp/types/session_info_update.rb +3 -42
- data/lib/acp/types/string_multi_select_items.rb +3 -29
- data/lib/acp/types/string_property_schema.rb +3 -105
- data/lib/acp/types/terminal.rb +3 -29
- data/lib/acp/types/text_content.rb +3 -40
- data/lib/acp/types/tool_call.rb +3 -115
- data/lib/acp/types/unstable/compaction_summary_chunk.rb +3 -35
- data/lib/acp/types/unstable/compaction_update.rb +3 -56
- data/lib/acp/types/unstable/idle_state_update.rb +3 -40
- data/lib/acp/types/unstable/mcp_server_acp.rb +3 -35
- data/lib/acp/types/unstable/nes_edit_suggestion.rb +3 -61
- data/lib/acp/types/unstable/nes_jump_suggestion.rb +3 -45
- data/lib/acp/types/unstable/nes_rename_suggestion.rb +3 -51
- data/lib/acp/types/unstable/nes_search_and_replace_suggestion.rb +3 -60
- data/lib/acp/types/unstable/notice.rb +3 -41
- data/lib/acp/types/unstable/plan_file.rb +3 -35
- data/lib/acp/types/unstable/plan_items.rb +3 -38
- data/lib/acp/types/unstable/plan_markdown.rb +3 -35
- data/lib/acp/types/unstable/plan_removed.rb +3 -26
- data/lib/acp/types/unstable/plan_update.rb +3 -33
- data/lib/acp/types/unstable/requires_action_state_update.rb +3 -21
- data/lib/acp/types/unstable/running_state_update.rb +3 -21
- data/lib/acp/types/unstable/session_message.rb +3 -56
- data/lib/acp/types/unstable/session_message_chunk.rb +3 -53
- data/lib/acp/types/unstable/subagent_update.rb +3 -65
- data/lib/acp/types/unstable/unknown_state_update.rb +3 -21
- data/lib/acp/types/unstable.rb +20 -20
- data/lib/acp/types/usage_update.rb +3 -41
- data/lib/acp/types.rb +7 -246
- data/lib/acp/version.rb +1 -1
- data/sig/generated/acp/agent_connection/client.rbs +10 -19
- data/sig/generated/acp/agent_connection/optional_method/spec.rbs +32 -0
- data/sig/generated/acp/agent_connection/optional_method.rbs +3 -0
- data/sig/generated/acp/agent_connection.rbs +16 -24
- data/sig/generated/acp/agent_process.rbs +0 -13
- data/sig/generated/acp/client_connection/streams.rbs +94 -0
- data/sig/generated/acp/client_connection.rbs +100 -159
- data/sig/generated/acp/protocol.rbs +9 -0
- data/sig/generated/acp/request_error.rbs +7 -17
- data/sig/generated/acp/transport/cancellation.rbs +0 -7
- data/sig/generated/acp/transport/reply.rbs +0 -2
- data/sig/generated/acp/transport/stderr_logger.rbs +1 -2
- data/sig/generated/acp/transport/stdio.rbs +9 -21
- data/sig/generated/acp/types/audio_content.rbs +1 -27
- data/sig/generated/acp/types/auth_method_terminal.rbs +1 -35
- data/sig/generated/acp/types/available_commands_update.rbs +1 -19
- data/sig/generated/acp/types/boolean_property_schema.rbs +1 -27
- data/sig/generated/acp/types/check.rbs +115 -0
- data/sig/generated/acp/types/config_option_update.rbs +1 -19
- data/sig/generated/acp/types/content.rbs +1 -19
- data/sig/generated/acp/types/{elicitation_url_mode → create_elicitation_request/mode/form}/scope.rbs +2 -2
- data/sig/generated/acp/types/create_elicitation_request/mode/form.rbs +3 -3
- data/sig/generated/acp/types/{elicitation_form_mode → create_elicitation_request/mode/url}/scope.rbs +2 -2
- data/sig/generated/acp/types/create_elicitation_request/mode/url.rbs +3 -3
- data/sig/generated/acp/types/current_mode_update.rbs +1 -19
- data/sig/generated/acp/types/diff.rbs +1 -27
- data/sig/generated/acp/types/elicitation_accept_action.rbs +1 -15
- data/sig/generated/acp/types/elicitation_form_mode.rbs +1 -19
- data/sig/generated/acp/types/elicitation_url_mode.rbs +1 -23
- data/sig/generated/acp/types/embedded_resource.rbs +1 -23
- data/sig/generated/acp/types/image_content.rbs +1 -31
- data/sig/generated/acp/types/integer_property_schema.rbs +1 -35
- data/sig/generated/acp/types/mcp_server_http.rbs +1 -27
- data/sig/generated/acp/types/mcp_server_sse.rbs +1 -27
- data/sig/generated/acp/types/multi_select_property_schema.rbs +1 -39
- data/sig/generated/acp/types/number_property_schema.rbs +1 -35
- data/sig/generated/acp/types/parse_error.rbs +22 -0
- data/sig/generated/acp/types/plan.rbs +1 -19
- data/sig/generated/acp/types/resource_link.rbs +1 -43
- data/sig/generated/acp/types/selected_permission_outcome.rbs +1 -19
- data/sig/generated/acp/types/session_config_boolean.rbs +1 -15
- data/sig/generated/acp/types/session_config_select.rbs +1 -19
- data/sig/generated/acp/types/session_info_update.rbs +1 -23
- data/sig/generated/acp/types/string_multi_select_items.rbs +1 -19
- data/sig/generated/acp/types/string_property_schema.rbs +1 -51
- data/sig/generated/acp/types/terminal.rbs +1 -19
- data/sig/generated/acp/types/text_content.rbs +1 -23
- data/sig/generated/acp/types/tool_call.rbs +1 -51
- data/sig/generated/acp/types/unstable/compaction_summary_chunk.rbs +1 -23
- data/sig/generated/acp/types/unstable/compaction_update.rbs +1 -31
- data/sig/generated/acp/types/unstable/idle_state_update.rbs +1 -23
- data/sig/generated/acp/types/unstable/mcp_server_acp.rbs +1 -23
- data/sig/generated/acp/types/unstable/nes_edit_suggestion.rbs +1 -31
- data/sig/generated/acp/types/unstable/nes_jump_suggestion.rbs +1 -27
- data/sig/generated/acp/types/unstable/nes_rename_suggestion.rbs +1 -31
- data/sig/generated/acp/types/unstable/nes_search_and_replace_suggestion.rbs +1 -35
- data/sig/generated/acp/types/unstable/notice.rbs +1 -27
- data/sig/generated/acp/types/unstable/plan_file.rbs +1 -23
- data/sig/generated/acp/types/unstable/plan_items.rbs +1 -23
- data/sig/generated/acp/types/unstable/plan_markdown.rbs +1 -23
- data/sig/generated/acp/types/unstable/plan_removed.rbs +1 -19
- data/sig/generated/acp/types/unstable/plan_update.rbs +1 -19
- data/sig/generated/acp/types/unstable/requires_action_state_update.rbs +1 -15
- data/sig/generated/acp/types/unstable/running_state_update.rbs +1 -15
- data/sig/generated/acp/types/unstable/session_message.rbs +1 -31
- data/sig/generated/acp/types/unstable/session_message_chunk.rbs +1 -31
- data/sig/generated/acp/types/unstable/subagent_update.rbs +1 -35
- data/sig/generated/acp/types/unstable/unknown_state_update.rbs +1 -15
- data/sig/generated/acp/types/usage_update.rbs +1 -27
- data/sig/generated/acp/types.rbs +6 -143
- data/sig/manual/acp/agent_connection.rbs +0 -30
- data/sig/manual/acp/client_connection.rbs +7 -2
- data/sig/manual/acp/{agent_connection/optional_method/logout.rbs → protocol.rbs} +3 -3
- data/sig/manual/acp/transport/stdio.rbs +0 -2
- data/sig/manual/acp/transport.rbs +25 -2
- metadata +16 -40
- data/lib/acp/agent_connection/optional_method/authenticate.rb +0 -21
- data/lib/acp/agent_connection/optional_method/close_session.rb +0 -21
- data/lib/acp/agent_connection/optional_method/delete_session.rb +0 -21
- data/lib/acp/agent_connection/optional_method/disable_provider.rb +0 -23
- data/lib/acp/agent_connection/optional_method/fork_session.rb +0 -23
- data/lib/acp/agent_connection/optional_method/list_providers.rb +0 -23
- data/lib/acp/agent_connection/optional_method/list_sessions.rb +0 -21
- data/lib/acp/agent_connection/optional_method/load_session.rb +0 -21
- data/lib/acp/agent_connection/optional_method/logout.rb +0 -21
- data/lib/acp/agent_connection/optional_method/resume_session.rb +0 -21
- data/lib/acp/agent_connection/optional_method/set_provider.rb +0 -23
- data/lib/acp/types/content_chunk.rb +0 -40
- data/sig/generated/acp/agent_connection/optional_method/authenticate.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/close_session.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/delete_session.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/disable_provider.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/fork_session.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/list_providers.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/list_sessions.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/load_session.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/logout.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/resume_session.rbs +0 -13
- data/sig/generated/acp/agent_connection/optional_method/set_provider.rbs +0 -13
- data/sig/generated/acp/types/content_chunk.rbs +0 -25
- data/sig/manual/acp/agent_connection/optional_method/authenticate.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/close_session.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/delete_session.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/disable_provider.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/fork_session.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/list_providers.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/list_sessions.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/load_session.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/resume_session.rbs +0 -6
- data/sig/manual/acp/agent_connection/optional_method/set_provider.rbs +0 -6
data/lib/acp/protocol.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ACP::Protocol
|
|
4
|
+
PROTOCOL_VERSION = 1 #: Integer
|
|
5
|
+
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
# @rbs capabilities: (ACP::Types::AgentCapabilities | ACP::Types::Unstable::AgentCapabilities | Hash[String, untyped])
|
|
9
|
+
# @rbs return: bool
|
|
10
|
+
def mcp_acp_advertised?(capabilities)
|
|
11
|
+
# The stable McpCapabilities has no acp field, so the gate can only read it
|
|
12
|
+
# when the caller opted in with `require 'acp/types/unstable'`.
|
|
13
|
+
return false unless ACP::Types.unstable_enabled?
|
|
14
|
+
|
|
15
|
+
mcp =
|
|
16
|
+
case capabilities
|
|
17
|
+
when ACP::Types::AgentCapabilities, ACP::Types::Unstable::AgentCapabilities
|
|
18
|
+
capabilities.mcp_capabilities #: ACP::Types::McpCapabilities | ACP::Types::Unstable::McpCapabilities?
|
|
19
|
+
when Hash
|
|
20
|
+
# The client's stable parse of the initialize reply drops acp, so
|
|
21
|
+
# mcpCapabilities is re-parsed from the raw hash with the unstable
|
|
22
|
+
# type. Only that sub-object: the other unstable fields arrive
|
|
23
|
+
# unvalidated and must not decide whether MCP is advertised.
|
|
24
|
+
raw = capabilities['mcpCapabilities']
|
|
25
|
+
ACP::Types::Unstable::McpCapabilities.from_h(raw) if raw.is_a?(Hash)
|
|
26
|
+
end
|
|
27
|
+
return false unless mcp.is_a?(ACP::Types::Unstable::McpCapabilities)
|
|
28
|
+
|
|
29
|
+
mcp.acp ? true : false
|
|
30
|
+
rescue ACP::Types::ParseError
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/acp/request_error.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
# RequestError: built by handlers and local refusals, and decoded from a
|
|
5
|
-
# peer's error replies by the transport.
|
|
3
|
+
# Named after the official SDKs' RequestError rather than the schema's Error.
|
|
6
4
|
class ACP::RequestError
|
|
7
5
|
PARSE_ERROR = -32_700 #: Integer
|
|
8
6
|
INVALID_REQUEST = -32_600 #: Integer
|
|
@@ -60,9 +58,8 @@ class ACP::RequestError
|
|
|
60
58
|
new(code: INVALID_PARAMS, message: 'Invalid params', data: errors && { errors: errors })
|
|
61
59
|
end
|
|
62
60
|
|
|
63
|
-
# The
|
|
64
|
-
#
|
|
65
|
-
# apart from an unknown method.
|
|
61
|
+
# The message names the capability so the refusal can be told apart from an
|
|
62
|
+
# unknown method, though both use the -32601 code.
|
|
66
63
|
#
|
|
67
64
|
# @rbs capability: String
|
|
68
65
|
# @rbs return: ACP::RequestError
|
|
@@ -70,11 +67,9 @@ class ACP::RequestError
|
|
|
70
67
|
new(code: METHOD_NOT_FOUND, message: "Client does not advertise #{capability}")
|
|
71
68
|
end
|
|
72
69
|
|
|
73
|
-
# The
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
# mode in its params, so an unadvertised one is invalid params rather than
|
|
77
|
-
# method not found.
|
|
70
|
+
# The message names the mode so the refusal can be told apart from malformed
|
|
71
|
+
# params. The spec gives elicitation a mode in its params, so an unadvertised
|
|
72
|
+
# one is invalid params rather than method not found.
|
|
78
73
|
#
|
|
79
74
|
# @rbs mode: String
|
|
80
75
|
# @rbs return: ACP::RequestError
|
|
@@ -82,10 +77,6 @@ class ACP::RequestError
|
|
|
82
77
|
new(code: INVALID_PARAMS, message: "Client does not advertise #{mode}")
|
|
83
78
|
end
|
|
84
79
|
|
|
85
|
-
# unadvertised names a capability of the client's, this one a capability of
|
|
86
|
-
# the agent's: the same method-not-found code, with a message naming which
|
|
87
|
-
# side's advertisement is missing.
|
|
88
|
-
#
|
|
89
80
|
# @rbs capability: String
|
|
90
81
|
# @rbs return: ACP::RequestError
|
|
91
82
|
def self.unadvertised_agent(capability)
|
|
@@ -106,8 +97,7 @@ class ACP::RequestError
|
|
|
106
97
|
new(code: INTERNAL_ERROR, message: 'Invalid response', data: response)
|
|
107
98
|
end
|
|
108
99
|
|
|
109
|
-
#
|
|
110
|
-
# not speak; the message names both versions so logs can tell it from a
|
|
100
|
+
# The message names both versions so logs can tell this local refusal from a
|
|
111
101
|
# peer's error.
|
|
112
102
|
#
|
|
113
103
|
# @rbs requested: Integer
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Whether the peer cancelled one request. The transport creates one per served
|
|
4
|
-
# request, marks it when the peer's $/cancel_request arrives, and hands it to
|
|
5
|
-
# the serving thread, whose handler can observe it and end the request early.
|
|
6
3
|
class ACP::Transport::Cancellation
|
|
7
4
|
KEY = :acp_serving_cancellation #: Symbol
|
|
8
5
|
|
|
9
|
-
# Connections read this to expose the serving state to their handlers and
|
|
10
|
-
# write it to carry serving identity onto a thread they spawn; nil off a
|
|
11
|
-
# serve thread.
|
|
12
|
-
#
|
|
13
6
|
# @rbs return: ACP::Transport::Cancellation?
|
|
14
7
|
def self.current
|
|
15
8
|
Thread.current[KEY] #: ACP::Transport::Cancellation?
|
data/lib/acp/transport/reply.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# A request handler's outcome plus a callback the transport runs once that
|
|
4
|
-
# outcome is on the wire, for messages the peer must only see after the reply.
|
|
5
3
|
class ACP::Transport::Reply
|
|
6
4
|
# @dynamic result
|
|
7
5
|
attr_reader :result #: ACP::Transport::Stdio::_ToH
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# The
|
|
4
|
-
# sanctions agents logging to stderr.
|
|
3
|
+
# The spec sanctions agents logging to stderr.
|
|
5
4
|
class ACP::Transport::StderrLogger
|
|
6
5
|
# @rbs message: String
|
|
7
6
|
# @rbs return: void
|
data/lib/acp/transport/stdio.rb
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# that arrive meanwhile.
|
|
5
|
+
# A reader thread dispatches inbound messages while outbound requests are
|
|
6
|
+
# pending, and each inbound request is served on its own thread, so a handler
|
|
7
|
+
# can make an outbound request mid-turn and still see notifications (e.g.
|
|
8
|
+
# session/cancel) that arrive meanwhile.
|
|
10
9
|
class ACP::Transport::Stdio
|
|
11
10
|
# @rbs @input: _Reader
|
|
12
11
|
# @rbs @output: _Writer
|
|
@@ -38,9 +37,6 @@ class ACP::Transport::Stdio
|
|
|
38
37
|
@logger = logger
|
|
39
38
|
end
|
|
40
39
|
|
|
41
|
-
# Returns the reader thread, which ends at EOF on input after releasing any
|
|
42
|
-
# pending outbound requests.
|
|
43
|
-
#
|
|
44
40
|
# @rbs requests: Hash[String, _Handler]
|
|
45
41
|
# @rbs notifications: Hash[String, _NotificationHandler]
|
|
46
42
|
# @rbs return: Thread
|
|
@@ -55,14 +51,16 @@ class ACP::Transport::Stdio
|
|
|
55
51
|
|
|
56
52
|
# @rbs method: String
|
|
57
53
|
# @rbs params: untyped
|
|
58
|
-
# @rbs return:
|
|
54
|
+
# @rbs return: untyped
|
|
59
55
|
def request(method, params = nil)
|
|
60
56
|
queue = Thread::Queue.new
|
|
61
57
|
id = register(queue)
|
|
62
58
|
return CONNECTION_CLOSED unless id
|
|
63
59
|
|
|
64
60
|
write({ 'jsonrpc' => '2.0', 'id' => id, 'method' => method, 'params' => params }.compact)
|
|
65
|
-
queue.pop
|
|
61
|
+
result = queue.pop
|
|
62
|
+
# A null result pops nil just as a closed queue does.
|
|
63
|
+
queue.closed? ? CONNECTION_CLOSED : result
|
|
66
64
|
end
|
|
67
65
|
|
|
68
66
|
# @rbs method: String
|
|
@@ -90,11 +88,6 @@ class ACP::Transport::Stdio
|
|
|
90
88
|
@lock.synchronize { @pending.keys }.each { |id| cancel(id) }
|
|
91
89
|
end
|
|
92
90
|
|
|
93
|
-
# The cancellation of the request the calling thread is serving, or nil off
|
|
94
|
-
# a serve thread. A handler observes the peer's $/cancel_request through it
|
|
95
|
-
# and can end early with ACP::RequestError.request_cancelled; whatever it
|
|
96
|
-
# returns, the transport sends exactly one response.
|
|
97
|
-
#
|
|
98
91
|
# @rbs return: ACP::Transport::Cancellation?
|
|
99
92
|
def cancellation
|
|
100
93
|
ACP::Transport::Cancellation.current
|
|
@@ -137,8 +130,12 @@ class ACP::Transport::Stdio
|
|
|
137
130
|
elsif error.is_a?(Hash) && error['code'].is_a?(Integer) && error['message'].is_a?(String)
|
|
138
131
|
code, text, data = error.values_at('code', 'message', 'data')
|
|
139
132
|
settle(message['id'], ACP::RequestError.new(code:, message: text, data:))
|
|
140
|
-
|
|
133
|
+
elsif message.key?('method')
|
|
141
134
|
reply(detectable_id(message), ACP::RequestError.invalid_request)
|
|
135
|
+
elsif !settle(message['id'], ACP::RequestError.invalid_response(message))
|
|
136
|
+
# JSON-RPC responses only answer requests, so a malformed one is never
|
|
137
|
+
# replied to: the error could settle an unrelated request on the peer.
|
|
138
|
+
@logger.warn('dropped malformed response: no pending request for its id')
|
|
142
139
|
end
|
|
143
140
|
end
|
|
144
141
|
|
|
@@ -246,9 +243,6 @@ class ACP::Transport::Stdio
|
|
|
246
243
|
ACP::RequestError.internal_error
|
|
247
244
|
end
|
|
248
245
|
|
|
249
|
-
# The success arm is whatever the handler returned, which the transport only
|
|
250
|
-
# knows serializes with to_h; RequestError picks the error arm of the reply.
|
|
251
|
-
#
|
|
252
246
|
# @rbs id: untyped
|
|
253
247
|
# @rbs outcome: (_ToH | ACP::RequestError)
|
|
254
248
|
# @rbs return: void
|
|
@@ -273,10 +267,10 @@ class ACP::Transport::Stdio
|
|
|
273
267
|
end
|
|
274
268
|
|
|
275
269
|
# @rbs id: untyped
|
|
276
|
-
# @rbs result:
|
|
277
|
-
# @rbs return:
|
|
270
|
+
# @rbs result: untyped
|
|
271
|
+
# @rbs return: Thread::Queue?
|
|
278
272
|
def settle(id, result)
|
|
279
|
-
@lock.synchronize { @pending.delete(id) }&.push(result)
|
|
273
|
+
@lock.synchronize { @pending.delete(id) }&.tap { |queue| queue.push(result) }
|
|
280
274
|
end
|
|
281
275
|
|
|
282
276
|
# @rbs return: void
|
|
@@ -2,50 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Generated by bin/types from schema/schema.json. Do not edit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
attr_reader :annotations #: ACP::Types::Annotations?
|
|
5
|
+
# @rbs!
|
|
6
|
+
# class ACP::Types::AudioContent = ACP::Types::ContentBlock::Audio
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
attr_reader :data #: String
|
|
11
|
-
|
|
12
|
-
# @dynamic mime_type
|
|
13
|
-
attr_reader :mime_type #: String
|
|
14
|
-
|
|
15
|
-
# @dynamic meta
|
|
16
|
-
attr_reader :meta #: Hash[String, untyped]?
|
|
17
|
-
|
|
18
|
-
# @rbs annotations: ACP::Types::Annotations?
|
|
19
|
-
# @rbs data: String
|
|
20
|
-
# @rbs mime_type: String
|
|
21
|
-
# @rbs meta: Hash[String, untyped]?
|
|
22
|
-
# @rbs return: void
|
|
23
|
-
def initialize(data:, mime_type:, annotations: nil, meta: nil)
|
|
24
|
-
@annotations = annotations
|
|
25
|
-
@data = data
|
|
26
|
-
@mime_type = mime_type
|
|
27
|
-
@meta = meta
|
|
28
|
-
freeze
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @rbs hash: Hash[String, untyped]
|
|
32
|
-
# @rbs return: ACP::Types::AudioContent
|
|
33
|
-
def self.from_h(hash)
|
|
34
|
-
new(
|
|
35
|
-
annotations: ACP::Types::Check.object(
|
|
36
|
-
hash['annotations'],
|
|
37
|
-
'annotations',
|
|
38
|
-
ACP::Types::Annotations,
|
|
39
|
-
allow_nil: true
|
|
40
|
-
),
|
|
41
|
-
data: ACP::Types::Check.string(ACP::Types::Check.key(hash, 'data'), 'data'),
|
|
42
|
-
mime_type: ACP::Types::Check.string(ACP::Types::Check.key(hash, 'mimeType'), 'mimeType'),
|
|
43
|
-
meta: hash['_meta']
|
|
44
|
-
)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# @rbs return: Hash[String, untyped]
|
|
48
|
-
def to_h
|
|
49
|
-
{ 'data' => data, 'mimeType' => mime_type, 'annotations' => annotations&.to_h, '_meta' => meta }.compact
|
|
50
|
-
end
|
|
51
|
-
end
|
|
8
|
+
ACP::Types::AudioContent = ACP::Types::ContentBlock::Audio
|
|
@@ -2,63 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Generated by bin/types from schema/schema.json. Do not edit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
attr_reader :id #: String
|
|
5
|
+
# @rbs!
|
|
6
|
+
# class ACP::Types::AuthMethodTerminal = ACP::Types::AuthMethod::Terminal
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
attr_reader :name #: String
|
|
11
|
-
|
|
12
|
-
# @dynamic description
|
|
13
|
-
attr_reader :description #: String?
|
|
14
|
-
|
|
15
|
-
# @dynamic args
|
|
16
|
-
attr_reader :args #: Array[String]?
|
|
17
|
-
|
|
18
|
-
# @dynamic env
|
|
19
|
-
attr_reader :env #: Hash[String, String]?
|
|
20
|
-
|
|
21
|
-
# @dynamic meta
|
|
22
|
-
attr_reader :meta #: Hash[String, untyped]?
|
|
23
|
-
|
|
24
|
-
# @rbs id: String
|
|
25
|
-
# @rbs name: String
|
|
26
|
-
# @rbs description: String?
|
|
27
|
-
# @rbs args: Array[String]?
|
|
28
|
-
# @rbs env: Hash[String, String]?
|
|
29
|
-
# @rbs meta: Hash[String, untyped]?
|
|
30
|
-
# @rbs return: void
|
|
31
|
-
def initialize(id:, name:, description: nil, args: nil, env: nil, meta: nil)
|
|
32
|
-
@id = id
|
|
33
|
-
@name = name
|
|
34
|
-
@description = description
|
|
35
|
-
@args = args
|
|
36
|
-
@env = env
|
|
37
|
-
@meta = meta
|
|
38
|
-
freeze
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @rbs hash: Hash[String, untyped]
|
|
42
|
-
# @rbs return: ACP::Types::AuthMethodTerminal
|
|
43
|
-
def self.from_h(hash)
|
|
44
|
-
args = ACP::Types::Check.array(hash['args'], 'args', allow_nil: true) do |item, path|
|
|
45
|
-
ACP::Types::Check.string(item, path)
|
|
46
|
-
end
|
|
47
|
-
env = ACP::Types::Check.hash(hash['env'], 'env', allow_nil: true) do |value, path|
|
|
48
|
-
ACP::Types::Check.string(value, path)
|
|
49
|
-
end
|
|
50
|
-
new(
|
|
51
|
-
id: ACP::Types::Check.string(ACP::Types::Check.key(hash, 'id'), 'id'),
|
|
52
|
-
name: ACP::Types::Check.string(ACP::Types::Check.key(hash, 'name'), 'name'),
|
|
53
|
-
description: ACP::Types::Check.string(hash['description'], 'description', allow_nil: true),
|
|
54
|
-
args:,
|
|
55
|
-
env:,
|
|
56
|
-
meta: hash['_meta']
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# @rbs return: Hash[String, untyped]
|
|
61
|
-
def to_h
|
|
62
|
-
{ 'id' => id, 'name' => name, 'description' => description, 'args' => args, 'env' => env, '_meta' => meta }.compact
|
|
63
|
-
end
|
|
64
|
-
end
|
|
8
|
+
ACP::Types::AuthMethodTerminal = ACP::Types::AuthMethod::Terminal
|
|
@@ -2,36 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Generated by bin/types from schema/schema.json. Do not edit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
attr_reader :available_commands #: Array[ACP::Types::AvailableCommand]
|
|
5
|
+
# @rbs!
|
|
6
|
+
# class ACP::Types::AvailableCommandsUpdate = ACP::Types::SessionUpdate::AvailableCommandsUpdate
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
attr_reader :meta #: Hash[String, untyped]?
|
|
11
|
-
|
|
12
|
-
# @rbs available_commands: Array[ACP::Types::AvailableCommand]
|
|
13
|
-
# @rbs meta: Hash[String, untyped]?
|
|
14
|
-
# @rbs return: void
|
|
15
|
-
def initialize(available_commands:, meta: nil)
|
|
16
|
-
@available_commands = available_commands
|
|
17
|
-
@meta = meta
|
|
18
|
-
freeze
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# @rbs hash: Hash[String, untyped]
|
|
22
|
-
# @rbs return: ACP::Types::AvailableCommandsUpdate
|
|
23
|
-
def self.from_h(hash)
|
|
24
|
-
available_commands = ACP::Types::Check.array(
|
|
25
|
-
ACP::Types::Check.key(hash, 'availableCommands'),
|
|
26
|
-
'availableCommands'
|
|
27
|
-
) do |item, path|
|
|
28
|
-
ACP::Types::Check.object(item, path, ACP::Types::AvailableCommand)
|
|
29
|
-
end
|
|
30
|
-
new(available_commands:, meta: hash['_meta'])
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# @rbs return: Hash[String, untyped]
|
|
34
|
-
def to_h
|
|
35
|
-
{ 'availableCommands' => available_commands.map(&:to_h), '_meta' => meta }.compact
|
|
36
|
-
end
|
|
37
|
-
end
|
|
8
|
+
ACP::Types::AvailableCommandsUpdate = ACP::Types::SessionUpdate::AvailableCommandsUpdate
|
|
@@ -2,45 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Generated by bin/types from schema/schema.json. Do not edit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
attr_reader :title #: String?
|
|
5
|
+
# @rbs!
|
|
6
|
+
# class ACP::Types::BooleanPropertySchema = ACP::Types::ElicitationPropertySchema::BooleanPropertySchema
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
attr_reader :description #: String?
|
|
11
|
-
|
|
12
|
-
# @dynamic default
|
|
13
|
-
attr_reader :default #: bool?
|
|
14
|
-
|
|
15
|
-
# @dynamic meta
|
|
16
|
-
attr_reader :meta #: Hash[String, untyped]?
|
|
17
|
-
|
|
18
|
-
# @rbs title: String?
|
|
19
|
-
# @rbs description: String?
|
|
20
|
-
# @rbs default: bool?
|
|
21
|
-
# @rbs meta: Hash[String, untyped]?
|
|
22
|
-
# @rbs return: void
|
|
23
|
-
def initialize(title: nil, description: nil, default: nil, meta: nil)
|
|
24
|
-
@title = title
|
|
25
|
-
@description = description
|
|
26
|
-
@default = default
|
|
27
|
-
@meta = meta
|
|
28
|
-
freeze
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @rbs hash: Hash[String, untyped]
|
|
32
|
-
# @rbs return: ACP::Types::BooleanPropertySchema
|
|
33
|
-
def self.from_h(hash)
|
|
34
|
-
new(
|
|
35
|
-
title: ACP::Types::Check.string(hash['title'], 'title', allow_nil: true),
|
|
36
|
-
description: ACP::Types::Check.string(hash['description'], 'description', allow_nil: true),
|
|
37
|
-
default: ACP::Types::Check.boolean(hash['default'], 'default', allow_nil: true),
|
|
38
|
-
meta: hash['_meta']
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @rbs return: Hash[String, untyped]
|
|
43
|
-
def to_h
|
|
44
|
-
{ 'title' => title, 'description' => description, 'default' => default, '_meta' => meta }.compact
|
|
45
|
-
end
|
|
46
|
-
end
|
|
8
|
+
ACP::Types::BooleanPropertySchema = ACP::Types::ElicitationPropertySchema::BooleanPropertySchema
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Hand-authored support for the generated types: the generator neither emits
|
|
4
|
+
# nor deletes this file (see TypeGenerator::SUPPORT_FILES).
|
|
5
|
+
|
|
6
|
+
module ACP::Types::Check
|
|
7
|
+
# @rbs hash: Hash[String, untyped]
|
|
8
|
+
# @rbs key: String
|
|
9
|
+
# @rbs return: untyped
|
|
10
|
+
def self.key(hash, key)
|
|
11
|
+
hash.fetch(key)
|
|
12
|
+
rescue KeyError
|
|
13
|
+
raise ACP::Types::ParseError.new([key], 'is required')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs value: untyped
|
|
17
|
+
# @rbs path: String | Array[String | Integer]
|
|
18
|
+
# @rbs allow_nil: bool
|
|
19
|
+
# @rbs allow_unset: bool
|
|
20
|
+
# @rbs return: untyped
|
|
21
|
+
def self.string(value, path, allow_nil: false, allow_unset: false)
|
|
22
|
+
return value if value.is_a?(String) || skipped?(value, allow_nil, allow_unset)
|
|
23
|
+
|
|
24
|
+
raise ACP::Types::ParseError.new(segments(path), "expected String, got #{describe(value)}")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @rbs value: untyped
|
|
28
|
+
# @rbs path: String | Array[String | Integer]
|
|
29
|
+
# @rbs allow_nil: bool
|
|
30
|
+
# @rbs allow_unset: bool
|
|
31
|
+
# @rbs return: untyped
|
|
32
|
+
def self.boolean(value, path, allow_nil: false, allow_unset: false)
|
|
33
|
+
return value if value == true || value == false || skipped?(value, allow_nil, allow_unset)
|
|
34
|
+
|
|
35
|
+
raise ACP::Types::ParseError.new(segments(path), "expected boolean, got #{describe(value)}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @rbs value: untyped
|
|
39
|
+
# @rbs path: String | Array[String | Integer]
|
|
40
|
+
# @rbs min: Integer?
|
|
41
|
+
# @rbs max: Integer?
|
|
42
|
+
# @rbs allow_nil: bool
|
|
43
|
+
# @rbs allow_unset: bool
|
|
44
|
+
# @rbs return: untyped
|
|
45
|
+
def self.integer(value, path, min: nil, max: nil, allow_nil: false, allow_unset: false)
|
|
46
|
+
return value if (value.is_a?(Integer) && within?(value, min, max)) || skipped?(value, allow_nil, allow_unset)
|
|
47
|
+
|
|
48
|
+
raise ACP::Types::ParseError.new(segments(path), "expected #{bounded('Integer', min, max)}, got #{describe(value)}")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs value: untyped
|
|
52
|
+
# @rbs path: String | Array[String | Integer]
|
|
53
|
+
# @rbs min: Integer?
|
|
54
|
+
# @rbs max: Integer?
|
|
55
|
+
# @rbs allow_nil: bool
|
|
56
|
+
# @rbs allow_unset: bool
|
|
57
|
+
# @rbs return: untyped
|
|
58
|
+
def self.number(value, path, min: nil, max: nil, allow_nil: false, allow_unset: false)
|
|
59
|
+
return value if (value.is_a?(Numeric) && within?(value, min, max)) || skipped?(value, allow_nil, allow_unset)
|
|
60
|
+
|
|
61
|
+
raise ACP::Types::ParseError.new(segments(path), "expected #{bounded('Numeric', min, max)}, got #{describe(value)}")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @rbs value: untyped
|
|
65
|
+
# @rbs path: String | Array[String | Integer]
|
|
66
|
+
# @rbs values: Array[untyped]
|
|
67
|
+
# @rbs allow_nil: bool
|
|
68
|
+
# @rbs allow_unset: bool
|
|
69
|
+
# @rbs return: untyped
|
|
70
|
+
def self.enum(value, path, values, allow_nil: false, allow_unset: false)
|
|
71
|
+
return value if values.include?(value) || skipped?(value, allow_nil, allow_unset)
|
|
72
|
+
|
|
73
|
+
expected = values.map(&:inspect).join(', ')
|
|
74
|
+
raise ACP::Types::ParseError.new(segments(path), "expected one of #{expected}, got #{describe(value)}")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @rbs value: untyped
|
|
78
|
+
# @rbs path: String | Array[String | Integer]
|
|
79
|
+
# @rbs classes: Array[untyped]
|
|
80
|
+
# @rbs allow_nil: bool
|
|
81
|
+
# @rbs allow_unset: bool
|
|
82
|
+
# @rbs ?&items: (untyped, Array[String | Integer]) -> void
|
|
83
|
+
# @rbs return: untyped
|
|
84
|
+
def self.one_of(value, path, classes, allow_nil: false, allow_unset: false, &items)
|
|
85
|
+
return value if skipped?(value, allow_nil, allow_unset)
|
|
86
|
+
|
|
87
|
+
unless classes.any? { |klass| value.is_a?(klass) }
|
|
88
|
+
expected = classes.map(&:name).join(' | ')
|
|
89
|
+
raise ACP::Types::ParseError.new(segments(path), "expected #{expected}, got #{describe(value)}")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
return value unless value.is_a?(Array) && items
|
|
93
|
+
|
|
94
|
+
value.each_with_index { |item, index| yield(item, [*segments(path), index]) }
|
|
95
|
+
value
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @rbs value: untyped
|
|
99
|
+
# @rbs path: String | Array[String | Integer]
|
|
100
|
+
# @rbs allow_nil: bool
|
|
101
|
+
# @rbs allow_unset: bool
|
|
102
|
+
# @rbs &check: (untyped, Array[String | Integer]) -> void
|
|
103
|
+
# @rbs return: untyped
|
|
104
|
+
def self.hash(value, path, allow_nil: false, allow_unset: false, &check)
|
|
105
|
+
return value if skipped?(value, allow_nil, allow_unset)
|
|
106
|
+
raise ACP::Types::ParseError.new(segments(path), "expected object, got #{describe(value)}") unless value.is_a?(Hash)
|
|
107
|
+
|
|
108
|
+
parsed = {} #: Hash[String, untyped]
|
|
109
|
+
value.each { |key, item| parsed[key] = yield(item, [*segments(path), key]) }
|
|
110
|
+
parsed
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @rbs value: untyped
|
|
114
|
+
# @rbs path: String | Array[String | Integer]
|
|
115
|
+
# @rbs allow_nil: bool
|
|
116
|
+
# @rbs allow_unset: bool
|
|
117
|
+
# @rbs &check: (untyped, Array[String | Integer]) -> void
|
|
118
|
+
# @rbs return: untyped
|
|
119
|
+
def self.array(value, path, allow_nil: false, allow_unset: false, &check)
|
|
120
|
+
return value if skipped?(value, allow_nil, allow_unset)
|
|
121
|
+
raise ACP::Types::ParseError.new(segments(path), "expected array, got #{describe(value)}") unless value.is_a?(Array)
|
|
122
|
+
|
|
123
|
+
value.each_with_index.map { |item, index| yield(item, [*segments(path), index]) }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @rbs value: untyped
|
|
127
|
+
# @rbs path: String | Array[String | Integer]
|
|
128
|
+
# @rbs klass: untyped
|
|
129
|
+
# @rbs allow_nil: bool
|
|
130
|
+
# @rbs allow_unset: bool
|
|
131
|
+
# @rbs return: untyped
|
|
132
|
+
def self.object(value, path, klass, allow_nil: false, allow_unset: false)
|
|
133
|
+
return value if skipped?(value, allow_nil, allow_unset)
|
|
134
|
+
raise ACP::Types::ParseError.new(segments(path), "expected object, got #{describe(value)}") unless value.is_a?(Hash)
|
|
135
|
+
|
|
136
|
+
begin
|
|
137
|
+
klass.from_h(value)
|
|
138
|
+
rescue ACP::Types::ParseError => e
|
|
139
|
+
raise e.prefix(*segments(path))
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @rbs value: untyped
|
|
144
|
+
# @rbs path: String | Array[String | Integer]
|
|
145
|
+
# @rbs klass: untyped
|
|
146
|
+
# @rbs allow_nil: bool
|
|
147
|
+
# @rbs allow_unset: bool
|
|
148
|
+
# @rbs return: untyped
|
|
149
|
+
def self.objects(value, path, klass, allow_nil: false, allow_unset: false)
|
|
150
|
+
return value if skipped?(value, allow_nil, allow_unset)
|
|
151
|
+
raise ACP::Types::ParseError.new(segments(path), "expected array, got #{describe(value)}") unless value.is_a?(Array)
|
|
152
|
+
|
|
153
|
+
value.each_with_index do |item, index|
|
|
154
|
+
next if item.is_a?(Hash)
|
|
155
|
+
|
|
156
|
+
raise ACP::Types::ParseError.new([*segments(path), index], "expected object, got #{describe(item)}")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
begin
|
|
160
|
+
klass.from_a(value)
|
|
161
|
+
rescue ACP::Types::ParseError => e
|
|
162
|
+
raise e.prefix(*segments(path))
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @rbs value: untyped
|
|
167
|
+
# @rbs allow_nil: bool
|
|
168
|
+
# @rbs allow_unset: bool
|
|
169
|
+
# @rbs return: bool
|
|
170
|
+
def self.skipped?(value, allow_nil, allow_unset)
|
|
171
|
+
(value.nil? && allow_nil) || (allow_unset && value.equal?(:unset))
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @rbs path: String | Array[String | Integer]
|
|
175
|
+
# @rbs return: Array[String | Integer]
|
|
176
|
+
def self.segments(path)
|
|
177
|
+
path.is_a?(Array) ? path : [path]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @rbs value: untyped
|
|
181
|
+
# @rbs return: String
|
|
182
|
+
def self.describe(value)
|
|
183
|
+
case value
|
|
184
|
+
when nil then 'null'
|
|
185
|
+
when true then 'true'
|
|
186
|
+
when false then 'false'
|
|
187
|
+
else value.class.name
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @rbs value: Numeric
|
|
192
|
+
# @rbs min: Integer?
|
|
193
|
+
# @rbs max: Integer?
|
|
194
|
+
# @rbs return: bool
|
|
195
|
+
def self.within?(value, min, max)
|
|
196
|
+
(min.nil? || value >= min) && (max.nil? || value <= max)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# @rbs name: String
|
|
200
|
+
# @rbs min: Integer?
|
|
201
|
+
# @rbs max: Integer?
|
|
202
|
+
# @rbs return: String
|
|
203
|
+
def self.bounded(name, min, max)
|
|
204
|
+
if min && max then "#{name} between #{min} and #{max}"
|
|
205
|
+
elsif min then "#{name} >= #{min}"
|
|
206
|
+
elsif max then "#{name} <= #{max}"
|
|
207
|
+
else name
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -2,36 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Generated by bin/types from schema/schema.json. Do not edit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
attr_reader :config_options #: Array[ACP::Types::SessionConfigOption]
|
|
5
|
+
# @rbs!
|
|
6
|
+
# class ACP::Types::ConfigOptionUpdate = ACP::Types::SessionUpdate::ConfigOptionUpdate
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
attr_reader :meta #: Hash[String, untyped]?
|
|
11
|
-
|
|
12
|
-
# @rbs config_options: Array[ACP::Types::SessionConfigOption]
|
|
13
|
-
# @rbs meta: Hash[String, untyped]?
|
|
14
|
-
# @rbs return: void
|
|
15
|
-
def initialize(config_options:, meta: nil)
|
|
16
|
-
@config_options = config_options
|
|
17
|
-
@meta = meta
|
|
18
|
-
freeze
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# @rbs hash: Hash[String, untyped]
|
|
22
|
-
# @rbs return: ACP::Types::ConfigOptionUpdate
|
|
23
|
-
def self.from_h(hash)
|
|
24
|
-
config_options = ACP::Types::Check.array(
|
|
25
|
-
ACP::Types::Check.key(hash, 'configOptions'),
|
|
26
|
-
'configOptions'
|
|
27
|
-
) do |item, path|
|
|
28
|
-
ACP::Types::Check.object(item, path, ACP::Types::SessionConfigOption)
|
|
29
|
-
end
|
|
30
|
-
new(config_options:, meta: hash['_meta'])
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# @rbs return: Hash[String, untyped]
|
|
34
|
-
def to_h
|
|
35
|
-
{ 'configOptions' => config_options.map(&:to_h), '_meta' => meta }.compact
|
|
36
|
-
end
|
|
37
|
-
end
|
|
8
|
+
ACP::Types::ConfigOptionUpdate = ACP::Types::SessionUpdate::ConfigOptionUpdate
|