acp-sdk 0.2.0 → 0.4.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 +29 -16
- data/lib/acp/agent_connection/client.rb +27 -12
- data/lib/acp/agent_connection/optional_method/logout.rb +21 -0
- data/lib/acp/agent_connection.rb +21 -32
- data/lib/acp/agent_process.rb +119 -0
- data/lib/acp/client_connection.rb +15 -15
- data/lib/acp/request_error.rb +90 -0
- data/lib/acp/transport/reply.rb +4 -4
- data/lib/acp/transport/stdio.rb +28 -25
- data/lib/acp/types/session_update/tool_call.rb +8 -0
- data/lib/acp/types/session_update/tool_call_update.rb +8 -0
- data/lib/acp/types/tool_call.rb +8 -0
- data/lib/acp/types/tool_call_update.rb +8 -0
- data/lib/acp/version.rb +1 -1
- data/sig/generated/acp/agent_connection/client.rbs +23 -16
- data/sig/generated/acp/agent_connection/optional_method/logout.rbs +13 -0
- data/sig/generated/acp/agent_connection.rbs +9 -15
- data/sig/generated/acp/agent_process.rbs +72 -0
- data/sig/generated/acp/client_connection.rbs +16 -16
- data/sig/generated/acp/request_error.rbs +72 -0
- data/sig/generated/acp/transport/reply.rbs +5 -5
- data/sig/generated/acp/transport/stdio.rbs +14 -19
- data/sig/generated/acp/types/session_update/tool_call.rbs +5 -1
- data/sig/generated/acp/types/session_update/tool_call_update.rbs +5 -1
- data/sig/generated/acp/types/tool_call.rbs +5 -1
- data/sig/generated/acp/types/tool_call_update.rbs +5 -1
- data/sig/manual/acp/agent_connection/optional_method/logout.rbs +6 -0
- data/sig/manual/acp/agent_connection.rbs +24 -19
- data/sig/manual/acp/agent_process.rbs +7 -0
- data/sig/manual/acp/client_connection.rbs +1 -1
- data/sig/manual/acp/transport/stdio.rbs +7 -1
- metadata +9 -5
- data/lib/acp/transport/response_error.rb +0 -28
- data/lib/acp/transport/result.rb +0 -35
- data/sig/generated/acp/transport/response_error.rbs +0 -21
- data/sig/generated/acp/transport/result.rbs +0 -25
data/lib/acp/transport/stdio.rb
CHANGED
|
@@ -16,11 +16,9 @@ class ACP::Transport::Stdio
|
|
|
16
16
|
# @rbs @next_id: Integer
|
|
17
17
|
# @rbs @closed: bool
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
METHOD_NOT_FOUND = ACP::Transport::ResponseError.new(code: -32_601, message: 'Method not found') #: ACP::Transport::ResponseError
|
|
23
|
-
CONNECTION_CLOSED = ACP::Transport::ResponseError.new(code: INTERNAL_ERROR, message: 'Connection closed') #: ACP::Transport::ResponseError
|
|
19
|
+
CONNECTION_CLOSED = ACP::RequestError.new(
|
|
20
|
+
code: ACP::RequestError::INTERNAL_ERROR, message: 'Connection closed'
|
|
21
|
+
) #: ACP::RequestError
|
|
24
22
|
|
|
25
23
|
# @rbs input: _Reader
|
|
26
24
|
# @rbs output: _Writer
|
|
@@ -52,14 +50,14 @@ class ACP::Transport::Stdio
|
|
|
52
50
|
|
|
53
51
|
# @rbs method: String
|
|
54
52
|
# @rbs params: untyped
|
|
55
|
-
# @rbs return: ACP::
|
|
53
|
+
# @rbs return: (Hash[String, untyped] | ACP::RequestError)
|
|
56
54
|
def request(method, params = nil)
|
|
57
55
|
queue = Thread::Queue.new
|
|
58
56
|
id = register(queue)
|
|
59
|
-
return
|
|
57
|
+
return CONNECTION_CLOSED unless id
|
|
60
58
|
|
|
61
59
|
write({ 'jsonrpc' => '2.0', 'id' => id, 'method' => method, 'params' => params }.compact)
|
|
62
|
-
queue.pop ||
|
|
60
|
+
queue.pop || CONNECTION_CLOSED
|
|
63
61
|
end
|
|
64
62
|
|
|
65
63
|
# @rbs method: String
|
|
@@ -78,7 +76,7 @@ class ACP::Transport::Stdio
|
|
|
78
76
|
def receive(line, requests, notifications)
|
|
79
77
|
message = parse(line)
|
|
80
78
|
case message
|
|
81
|
-
when ACP::
|
|
79
|
+
when ACP::RequestError then reply(nil, message)
|
|
82
80
|
else route(message, requests, notifications)
|
|
83
81
|
end
|
|
84
82
|
end
|
|
@@ -98,25 +96,24 @@ class ACP::Transport::Stdio
|
|
|
98
96
|
handler = notifications[method]
|
|
99
97
|
quietly { handler.call(message['params']) } if handler
|
|
100
98
|
elsif message.key?('result')
|
|
101
|
-
settle(message['id'],
|
|
99
|
+
settle(message['id'], message['result'])
|
|
102
100
|
elsif error.is_a?(Hash) && error['code'].is_a?(Integer) && error['message'].is_a?(String)
|
|
103
101
|
code, text, data = error.values_at('code', 'message', 'data')
|
|
104
|
-
|
|
105
|
-
settle(message['id'], ACP::Transport::Result.error(response_error))
|
|
102
|
+
settle(message['id'], ACP::RequestError.new(code:, message: text, data:))
|
|
106
103
|
else
|
|
107
|
-
reply(nil, ACP::
|
|
104
|
+
reply(nil, ACP::RequestError.invalid_request)
|
|
108
105
|
end
|
|
109
106
|
end
|
|
110
107
|
|
|
111
108
|
# @rbs line: String
|
|
112
|
-
# @rbs return: Hash[String, untyped] | ACP::
|
|
109
|
+
# @rbs return: Hash[String, untyped] | ACP::RequestError
|
|
113
110
|
def parse(line)
|
|
114
|
-
return
|
|
111
|
+
return ACP::RequestError.parse_error unless line.valid_encoding?
|
|
115
112
|
|
|
116
113
|
message = JSON.parse(line)
|
|
117
|
-
message.is_a?(Hash) ? message :
|
|
114
|
+
message.is_a?(Hash) ? message : ACP::RequestError.invalid_request
|
|
118
115
|
rescue JSON::ParserError
|
|
119
|
-
|
|
116
|
+
ACP::RequestError.parse_error
|
|
120
117
|
end
|
|
121
118
|
|
|
122
119
|
# @rbs handler: _Handler?
|
|
@@ -125,7 +122,7 @@ class ACP::Transport::Stdio
|
|
|
125
122
|
# @rbs return: void
|
|
126
123
|
def serve(handler, id, params)
|
|
127
124
|
Thread.new do
|
|
128
|
-
outcome = handler ? invoke(handler, params) : ACP::
|
|
125
|
+
outcome = handler ? invoke(handler, params) : ACP::RequestError.method_not_found
|
|
129
126
|
case outcome
|
|
130
127
|
when ACP::Transport::Reply
|
|
131
128
|
reply(id, outcome.result)
|
|
@@ -152,19 +149,25 @@ class ACP::Transport::Stdio
|
|
|
152
149
|
#
|
|
153
150
|
# @rbs handler: _Handler
|
|
154
151
|
# @rbs params: untyped
|
|
155
|
-
# @rbs return: ACP::
|
|
152
|
+
# @rbs return: (_ToH | ACP::RequestError | ACP::Transport::Reply)
|
|
156
153
|
def invoke(handler, params)
|
|
157
154
|
handler.call(params)
|
|
158
155
|
rescue StandardError => e
|
|
159
|
-
ACP::
|
|
156
|
+
ACP::RequestError.new(code: ACP::RequestError::INTERNAL_ERROR, message: e.message)
|
|
160
157
|
end
|
|
161
158
|
|
|
159
|
+
# The success arm is whatever the handler returned, which the transport only
|
|
160
|
+
# knows serializes with to_h; RequestError picks the error arm of the reply.
|
|
161
|
+
#
|
|
162
162
|
# @rbs id: untyped
|
|
163
|
-
# @rbs
|
|
163
|
+
# @rbs outcome: (_ToH | ACP::RequestError)
|
|
164
164
|
# @rbs return: void
|
|
165
|
-
def reply(id,
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
def reply(id, outcome)
|
|
166
|
+
payload = case outcome
|
|
167
|
+
when ACP::RequestError then { 'error' => outcome.to_h }
|
|
168
|
+
else { 'result' => outcome.to_h }
|
|
169
|
+
end
|
|
170
|
+
write({ 'jsonrpc' => '2.0', 'id' => id }.merge(payload))
|
|
168
171
|
end
|
|
169
172
|
|
|
170
173
|
# @rbs queue: Thread::Queue
|
|
@@ -180,7 +183,7 @@ class ACP::Transport::Stdio
|
|
|
180
183
|
end
|
|
181
184
|
|
|
182
185
|
# @rbs id: untyped
|
|
183
|
-
# @rbs result: ACP::
|
|
186
|
+
# @rbs result: (Hash[String, untyped] | ACP::RequestError)
|
|
184
187
|
# @rbs return: void
|
|
185
188
|
def settle(id, result)
|
|
186
189
|
@lock.synchronize { @pending.delete(id) }&.push(result)
|
|
@@ -9,6 +9,9 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
9
9
|
# @dynamic title
|
|
10
10
|
attr_reader :title #: String
|
|
11
11
|
|
|
12
|
+
# @dynamic name
|
|
13
|
+
attr_reader :name #: String?
|
|
14
|
+
|
|
12
15
|
# @dynamic kind
|
|
13
16
|
attr_reader :kind #: String?
|
|
14
17
|
|
|
@@ -32,6 +35,7 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
32
35
|
|
|
33
36
|
# @rbs tool_call_id: String
|
|
34
37
|
# @rbs title: String
|
|
38
|
+
# @rbs name: String?
|
|
35
39
|
# @rbs kind: String?
|
|
36
40
|
# @rbs status: String?
|
|
37
41
|
# @rbs content: Array[ACP::Types::ToolCallContent::t]?
|
|
@@ -43,6 +47,7 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
43
47
|
def initialize(
|
|
44
48
|
tool_call_id:,
|
|
45
49
|
title:,
|
|
50
|
+
name: nil,
|
|
46
51
|
kind: nil,
|
|
47
52
|
status: nil,
|
|
48
53
|
content: nil,
|
|
@@ -53,6 +58,7 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
53
58
|
)
|
|
54
59
|
@tool_call_id = tool_call_id
|
|
55
60
|
@title = title
|
|
61
|
+
@name = name
|
|
56
62
|
@kind = kind
|
|
57
63
|
@status = status
|
|
58
64
|
@content = content
|
|
@@ -69,6 +75,7 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
69
75
|
new(
|
|
70
76
|
tool_call_id: hash.fetch('toolCallId'),
|
|
71
77
|
title: hash.fetch('title'),
|
|
78
|
+
name: hash['name'],
|
|
72
79
|
kind: hash['kind'],
|
|
73
80
|
status: hash['status'],
|
|
74
81
|
content: hash['content']&.map { |item| ACP::Types::ToolCallContent.from_h(item) },
|
|
@@ -85,6 +92,7 @@ class ACP::Types::SessionUpdate::ToolCall
|
|
|
85
92
|
'sessionUpdate' => 'tool_call',
|
|
86
93
|
'toolCallId' => tool_call_id,
|
|
87
94
|
'title' => title,
|
|
95
|
+
'name' => name,
|
|
88
96
|
'kind' => kind,
|
|
89
97
|
'status' => status,
|
|
90
98
|
'content' => content&.map(&:to_h),
|
|
@@ -15,6 +15,9 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
15
15
|
# @dynamic title
|
|
16
16
|
attr_reader :title #: String?
|
|
17
17
|
|
|
18
|
+
# @dynamic name
|
|
19
|
+
attr_reader :name #: String?
|
|
20
|
+
|
|
18
21
|
# @dynamic content
|
|
19
22
|
attr_reader :content #: Array[ACP::Types::ToolCallContent::t]?
|
|
20
23
|
|
|
@@ -34,6 +37,7 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
34
37
|
# @rbs kind: String?
|
|
35
38
|
# @rbs status: String?
|
|
36
39
|
# @rbs title: String?
|
|
40
|
+
# @rbs name: String?
|
|
37
41
|
# @rbs content: Array[ACP::Types::ToolCallContent::t]?
|
|
38
42
|
# @rbs locations: Array[ACP::Types::ToolCallLocation]?
|
|
39
43
|
# @rbs raw_input: untyped
|
|
@@ -45,6 +49,7 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
45
49
|
kind: nil,
|
|
46
50
|
status: nil,
|
|
47
51
|
title: nil,
|
|
52
|
+
name: nil,
|
|
48
53
|
content: nil,
|
|
49
54
|
locations: nil,
|
|
50
55
|
raw_input: nil,
|
|
@@ -55,6 +60,7 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
55
60
|
@kind = kind
|
|
56
61
|
@status = status
|
|
57
62
|
@title = title
|
|
63
|
+
@name = name
|
|
58
64
|
@content = content
|
|
59
65
|
@locations = locations
|
|
60
66
|
@raw_input = raw_input
|
|
@@ -71,6 +77,7 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
71
77
|
kind: hash['kind'],
|
|
72
78
|
status: hash['status'],
|
|
73
79
|
title: hash['title'],
|
|
80
|
+
name: hash['name'],
|
|
74
81
|
content: hash['content']&.map { |item| ACP::Types::ToolCallContent.from_h(item) },
|
|
75
82
|
locations: hash['locations']&.map { |item| ACP::Types::ToolCallLocation.from_h(item) },
|
|
76
83
|
raw_input: hash['rawInput'],
|
|
@@ -87,6 +94,7 @@ class ACP::Types::SessionUpdate::ToolCallUpdate
|
|
|
87
94
|
'kind' => kind,
|
|
88
95
|
'status' => status,
|
|
89
96
|
'title' => title,
|
|
97
|
+
'name' => name,
|
|
90
98
|
'content' => content&.map(&:to_h),
|
|
91
99
|
'locations' => locations&.map(&:to_h),
|
|
92
100
|
'rawInput' => raw_input,
|
data/lib/acp/types/tool_call.rb
CHANGED
|
@@ -9,6 +9,9 @@ class ACP::Types::ToolCall
|
|
|
9
9
|
# @dynamic title
|
|
10
10
|
attr_reader :title #: String
|
|
11
11
|
|
|
12
|
+
# @dynamic name
|
|
13
|
+
attr_reader :name #: String?
|
|
14
|
+
|
|
12
15
|
# @dynamic kind
|
|
13
16
|
attr_reader :kind #: String?
|
|
14
17
|
|
|
@@ -32,6 +35,7 @@ class ACP::Types::ToolCall
|
|
|
32
35
|
|
|
33
36
|
# @rbs tool_call_id: String
|
|
34
37
|
# @rbs title: String
|
|
38
|
+
# @rbs name: String?
|
|
35
39
|
# @rbs kind: String?
|
|
36
40
|
# @rbs status: String?
|
|
37
41
|
# @rbs content: Array[ACP::Types::ToolCallContent::t]?
|
|
@@ -43,6 +47,7 @@ class ACP::Types::ToolCall
|
|
|
43
47
|
def initialize(
|
|
44
48
|
tool_call_id:,
|
|
45
49
|
title:,
|
|
50
|
+
name: nil,
|
|
46
51
|
kind: nil,
|
|
47
52
|
status: nil,
|
|
48
53
|
content: nil,
|
|
@@ -53,6 +58,7 @@ class ACP::Types::ToolCall
|
|
|
53
58
|
)
|
|
54
59
|
@tool_call_id = tool_call_id
|
|
55
60
|
@title = title
|
|
61
|
+
@name = name
|
|
56
62
|
@kind = kind
|
|
57
63
|
@status = status
|
|
58
64
|
@content = content
|
|
@@ -69,6 +75,7 @@ class ACP::Types::ToolCall
|
|
|
69
75
|
new(
|
|
70
76
|
tool_call_id: hash.fetch('toolCallId'),
|
|
71
77
|
title: hash.fetch('title'),
|
|
78
|
+
name: hash['name'],
|
|
72
79
|
kind: hash['kind'],
|
|
73
80
|
status: hash['status'],
|
|
74
81
|
content: hash['content']&.map { |item| ACP::Types::ToolCallContent.from_h(item) },
|
|
@@ -84,6 +91,7 @@ class ACP::Types::ToolCall
|
|
|
84
91
|
{
|
|
85
92
|
'toolCallId' => tool_call_id,
|
|
86
93
|
'title' => title,
|
|
94
|
+
'name' => name,
|
|
87
95
|
'kind' => kind,
|
|
88
96
|
'status' => status,
|
|
89
97
|
'content' => content&.map(&:to_h),
|
|
@@ -15,6 +15,9 @@ class ACP::Types::ToolCallUpdate
|
|
|
15
15
|
# @dynamic title
|
|
16
16
|
attr_reader :title #: String?
|
|
17
17
|
|
|
18
|
+
# @dynamic name
|
|
19
|
+
attr_reader :name #: String?
|
|
20
|
+
|
|
18
21
|
# @dynamic content
|
|
19
22
|
attr_reader :content #: Array[ACP::Types::ToolCallContent::t]?
|
|
20
23
|
|
|
@@ -34,6 +37,7 @@ class ACP::Types::ToolCallUpdate
|
|
|
34
37
|
# @rbs kind: String?
|
|
35
38
|
# @rbs status: String?
|
|
36
39
|
# @rbs title: String?
|
|
40
|
+
# @rbs name: String?
|
|
37
41
|
# @rbs content: Array[ACP::Types::ToolCallContent::t]?
|
|
38
42
|
# @rbs locations: Array[ACP::Types::ToolCallLocation]?
|
|
39
43
|
# @rbs raw_input: untyped
|
|
@@ -45,6 +49,7 @@ class ACP::Types::ToolCallUpdate
|
|
|
45
49
|
kind: nil,
|
|
46
50
|
status: nil,
|
|
47
51
|
title: nil,
|
|
52
|
+
name: nil,
|
|
48
53
|
content: nil,
|
|
49
54
|
locations: nil,
|
|
50
55
|
raw_input: nil,
|
|
@@ -55,6 +60,7 @@ class ACP::Types::ToolCallUpdate
|
|
|
55
60
|
@kind = kind
|
|
56
61
|
@status = status
|
|
57
62
|
@title = title
|
|
63
|
+
@name = name
|
|
58
64
|
@content = content
|
|
59
65
|
@locations = locations
|
|
60
66
|
@raw_input = raw_input
|
|
@@ -71,6 +77,7 @@ class ACP::Types::ToolCallUpdate
|
|
|
71
77
|
kind: hash['kind'],
|
|
72
78
|
status: hash['status'],
|
|
73
79
|
title: hash['title'],
|
|
80
|
+
name: hash['name'],
|
|
74
81
|
content: hash['content']&.map { |item| ACP::Types::ToolCallContent.from_h(item) },
|
|
75
82
|
locations: hash['locations']&.map { |item| ACP::Types::ToolCallLocation.from_h(item) },
|
|
76
83
|
raw_input: hash['rawInput'],
|
|
@@ -86,6 +93,7 @@ class ACP::Types::ToolCallUpdate
|
|
|
86
93
|
'kind' => kind,
|
|
87
94
|
'status' => status,
|
|
88
95
|
'title' => title,
|
|
96
|
+
'name' => name,
|
|
89
97
|
'content' => content&.map(&:to_h),
|
|
90
98
|
'locations' => locations&.map(&:to_h),
|
|
91
99
|
'rawInput' => raw_input,
|
data/lib/acp/version.rb
CHANGED
|
@@ -24,36 +24,36 @@ class ACP::AgentConnection::Client
|
|
|
24
24
|
# closes.
|
|
25
25
|
#
|
|
26
26
|
# @rbs request: ACP::Types::RequestPermissionRequest
|
|
27
|
-
# @rbs return: ACP::Types::RequestPermissionResponse | ACP::
|
|
28
|
-
def request_permission: (ACP::Types::RequestPermissionRequest request) -> (ACP::Types::RequestPermissionResponse | ACP::
|
|
27
|
+
# @rbs return: ACP::Types::RequestPermissionResponse | ACP::RequestError
|
|
28
|
+
def request_permission: (ACP::Types::RequestPermissionRequest request) -> (ACP::Types::RequestPermissionResponse | ACP::RequestError)
|
|
29
29
|
|
|
30
30
|
# @rbs request: ACP::Types::ReadTextFileRequest
|
|
31
|
-
# @rbs return: ACP::Types::ReadTextFileResponse | ACP::
|
|
32
|
-
def read_text_file: (ACP::Types::ReadTextFileRequest request) -> (ACP::Types::ReadTextFileResponse | ACP::
|
|
31
|
+
# @rbs return: ACP::Types::ReadTextFileResponse | ACP::RequestError
|
|
32
|
+
def read_text_file: (ACP::Types::ReadTextFileRequest request) -> (ACP::Types::ReadTextFileResponse | ACP::RequestError)
|
|
33
33
|
|
|
34
34
|
# @rbs request: ACP::Types::WriteTextFileRequest
|
|
35
|
-
# @rbs return: ACP::Types::WriteTextFileResponse | ACP::
|
|
36
|
-
def write_text_file: (ACP::Types::WriteTextFileRequest request) -> (ACP::Types::WriteTextFileResponse | ACP::
|
|
35
|
+
# @rbs return: ACP::Types::WriteTextFileResponse | ACP::RequestError
|
|
36
|
+
def write_text_file: (ACP::Types::WriteTextFileRequest request) -> (ACP::Types::WriteTextFileResponse | ACP::RequestError)
|
|
37
37
|
|
|
38
38
|
# @rbs request: ACP::Types::CreateTerminalRequest
|
|
39
|
-
# @rbs return: ACP::Types::CreateTerminalResponse | ACP::
|
|
40
|
-
def create_terminal: (ACP::Types::CreateTerminalRequest request) -> (ACP::Types::CreateTerminalResponse | ACP::
|
|
39
|
+
# @rbs return: ACP::Types::CreateTerminalResponse | ACP::RequestError
|
|
40
|
+
def create_terminal: (ACP::Types::CreateTerminalRequest request) -> (ACP::Types::CreateTerminalResponse | ACP::RequestError)
|
|
41
41
|
|
|
42
42
|
# @rbs request: ACP::Types::TerminalOutputRequest
|
|
43
|
-
# @rbs return: ACP::Types::TerminalOutputResponse | ACP::
|
|
44
|
-
def terminal_output: (ACP::Types::TerminalOutputRequest request) -> (ACP::Types::TerminalOutputResponse | ACP::
|
|
43
|
+
# @rbs return: ACP::Types::TerminalOutputResponse | ACP::RequestError
|
|
44
|
+
def terminal_output: (ACP::Types::TerminalOutputRequest request) -> (ACP::Types::TerminalOutputResponse | ACP::RequestError)
|
|
45
45
|
|
|
46
46
|
# @rbs request: ACP::Types::WaitForTerminalExitRequest
|
|
47
|
-
# @rbs return: ACP::Types::WaitForTerminalExitResponse | ACP::
|
|
48
|
-
def wait_for_terminal_exit: (ACP::Types::WaitForTerminalExitRequest request) -> (ACP::Types::WaitForTerminalExitResponse | ACP::
|
|
47
|
+
# @rbs return: ACP::Types::WaitForTerminalExitResponse | ACP::RequestError
|
|
48
|
+
def wait_for_terminal_exit: (ACP::Types::WaitForTerminalExitRequest request) -> (ACP::Types::WaitForTerminalExitResponse | ACP::RequestError)
|
|
49
49
|
|
|
50
50
|
# @rbs request: ACP::Types::KillTerminalRequest
|
|
51
|
-
# @rbs return: ACP::Types::KillTerminalResponse | ACP::
|
|
52
|
-
def kill_terminal: (ACP::Types::KillTerminalRequest request) -> (ACP::Types::KillTerminalResponse | ACP::
|
|
51
|
+
# @rbs return: ACP::Types::KillTerminalResponse | ACP::RequestError
|
|
52
|
+
def kill_terminal: (ACP::Types::KillTerminalRequest request) -> (ACP::Types::KillTerminalResponse | ACP::RequestError)
|
|
53
53
|
|
|
54
54
|
# @rbs request: ACP::Types::ReleaseTerminalRequest
|
|
55
|
-
# @rbs return: ACP::Types::ReleaseTerminalResponse | ACP::
|
|
56
|
-
def release_terminal: (ACP::Types::ReleaseTerminalRequest request) -> (ACP::Types::ReleaseTerminalResponse | ACP::
|
|
55
|
+
# @rbs return: ACP::Types::ReleaseTerminalResponse | ACP::RequestError
|
|
56
|
+
def release_terminal: (ACP::Types::ReleaseTerminalRequest request) -> (ACP::Types::ReleaseTerminalResponse | ACP::RequestError)
|
|
57
57
|
|
|
58
58
|
private
|
|
59
59
|
|
|
@@ -68,4 +68,11 @@ class ACP::AgentConnection::Client
|
|
|
68
68
|
# @rbs request: ACP::AgentConnection::_Response
|
|
69
69
|
# @rbs return: untyped
|
|
70
70
|
def terminal_call: (String rpc_method, ACP::AgentConnection::_Parser type, ACP::AgentConnection::_Response request) -> untyped
|
|
71
|
+
|
|
72
|
+
# Same method-not-found code a peer would send, but with a message that says
|
|
73
|
+
# the refusal was local, so logs can tell the two cases apart.
|
|
74
|
+
#
|
|
75
|
+
# @rbs capability: String
|
|
76
|
+
# @rbs return: ACP::RequestError
|
|
77
|
+
def unadvertised: (String capability) -> ACP::RequestError
|
|
71
78
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Generated from lib/acp/agent_connection/optional_method/logout.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module ACP::AgentConnection::OptionalMethod::Logout
|
|
4
|
+
# @rbs return: String
|
|
5
|
+
def rpc_method: () -> String
|
|
6
|
+
|
|
7
|
+
# @rbs return: Symbol
|
|
8
|
+
def agent_method: () -> Symbol
|
|
9
|
+
|
|
10
|
+
# @rbs initialize_response: ACP::Types::InitializeResponse
|
|
11
|
+
# @rbs return: bool
|
|
12
|
+
def advertised?: (ACP::Types::InitializeResponse initialize_response) -> bool
|
|
13
|
+
end
|
|
@@ -9,8 +9,6 @@ class ACP::AgentConnection
|
|
|
9
9
|
|
|
10
10
|
PROTOCOL_VERSION: Integer
|
|
11
11
|
|
|
12
|
-
INVALID_PARAMS: ACP::Transport::ResponseError
|
|
13
|
-
|
|
14
12
|
OPTIONAL: Array[ACP::AgentConnection::_OptionalMethod]
|
|
15
13
|
|
|
16
14
|
# The schema has no initialize capability for modes or config options: an
|
|
@@ -33,8 +31,8 @@ class ACP::AgentConnection
|
|
|
33
31
|
|
|
34
32
|
# @rbs agent: ACP::AgentConnection::_Agent
|
|
35
33
|
# @rbs client: ACP::AgentConnection::Client
|
|
36
|
-
# @rbs return: Hash[String, ^(untyped) -> (ACP::
|
|
37
|
-
def requests: (ACP::AgentConnection::_Agent agent, ACP::AgentConnection::Client client) -> Hash[String, ^(untyped) -> (ACP::
|
|
34
|
+
# @rbs return: Hash[String, ^(untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply)]
|
|
35
|
+
def requests: (ACP::AgentConnection::_Agent agent, ACP::AgentConnection::Client client) -> Hash[String, ^(untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply)]
|
|
38
36
|
|
|
39
37
|
# @rbs agent: ACP::AgentConnection::_Agent
|
|
40
38
|
# @rbs return: Hash[String, ^(untyped) -> void]
|
|
@@ -43,24 +41,20 @@ class ACP::AgentConnection
|
|
|
43
41
|
# Generated from_h raises on a missing key or a value of the wrong shape.
|
|
44
42
|
#
|
|
45
43
|
# @rbs type: ACP::AgentConnection::_Parser
|
|
46
|
-
# @rbs &handle: (untyped) -> (ACP::
|
|
47
|
-
# @rbs return: ^(untyped) -> (ACP::
|
|
48
|
-
def route: (ACP::AgentConnection::_Parser type) { (untyped) -> (ACP::
|
|
49
|
-
|
|
50
|
-
# @rbs response: ACP::AgentConnection::_Response | ACP::Transport::ResponseError
|
|
51
|
-
# @rbs return: ACP::Transport::Result
|
|
52
|
-
def respond: (ACP::AgentConnection::_Response | ACP::Transport::ResponseError response) -> ACP::Transport::Result
|
|
44
|
+
# @rbs &handle: (untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply)
|
|
45
|
+
# @rbs return: ^(untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply)
|
|
46
|
+
def route: (ACP::AgentConnection::_Parser type) { (untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply) } -> ^(untyped) -> (ACP::AgentConnection::_Response | ACP::RequestError | ACP::Transport::Reply)
|
|
53
47
|
|
|
54
48
|
# @rbs client: ACP::AgentConnection::Client
|
|
55
49
|
# @rbs request: ACP::Types::InitializeRequest
|
|
56
|
-
# @rbs return: ACP::
|
|
57
|
-
def connect: (ACP::AgentConnection::Client client, ACP::Types::InitializeRequest request) -> ACP::
|
|
50
|
+
# @rbs return: ACP::Types::InitializeResponse
|
|
51
|
+
def connect: (ACP::AgentConnection::Client client, ACP::Types::InitializeRequest request) -> ACP::Types::InitializeResponse
|
|
58
52
|
|
|
59
53
|
# session_created runs after the reply because the client must know the
|
|
60
54
|
# session id before updates for it (e.g. available commands) arrive.
|
|
61
55
|
#
|
|
62
56
|
# @rbs agent: ACP::AgentConnection::_Agent
|
|
63
57
|
# @rbs request: ACP::Types::NewSessionRequest
|
|
64
|
-
# @rbs return: ACP::
|
|
65
|
-
def new_session: (ACP::AgentConnection::_Agent agent, ACP::Types::NewSessionRequest request) -> (ACP::
|
|
58
|
+
# @rbs return: (ACP::Types::NewSessionResponse | ACP::RequestError | ACP::Transport::Reply)
|
|
59
|
+
def new_session: (ACP::AgentConnection::_Agent agent, ACP::Types::NewSessionRequest request) -> (ACP::Types::NewSessionResponse | ACP::RequestError | ACP::Transport::Reply)
|
|
66
60
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Generated from lib/acp/agent_process.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# A child agent process and the ACP::ClientConnection wired to its stdio.
|
|
4
|
+
# Spawn one with ACP::AgentProcess.spawn.
|
|
5
|
+
class ACP::AgentProcess
|
|
6
|
+
@stderr: String?
|
|
7
|
+
|
|
8
|
+
@err_reader: Thread?
|
|
9
|
+
|
|
10
|
+
@err_r: IO?
|
|
11
|
+
|
|
12
|
+
@waiter: Process::Waiter
|
|
13
|
+
|
|
14
|
+
@stdout: IO
|
|
15
|
+
|
|
16
|
+
@stdin: IO
|
|
17
|
+
|
|
18
|
+
@pid: Integer
|
|
19
|
+
|
|
20
|
+
@reader: Thread
|
|
21
|
+
|
|
22
|
+
@connection: ACP::ClientConnection
|
|
23
|
+
|
|
24
|
+
# @dynamic pid
|
|
25
|
+
attr_reader pid: Integer
|
|
26
|
+
|
|
27
|
+
# @dynamic connection
|
|
28
|
+
attr_reader connection: ACP::ClientConnection
|
|
29
|
+
|
|
30
|
+
# Child stderr captured when spawn was given stderr: :capture, else nil.
|
|
31
|
+
#
|
|
32
|
+
# @dynamic stderr
|
|
33
|
+
attr_reader stderr: String?
|
|
34
|
+
|
|
35
|
+
# Starts a command with args, env and cwd, wires its stdio to a new
|
|
36
|
+
# ACP::ClientConnection and starts it. With a block, yields the connection
|
|
37
|
+
# and this process, then terminates the child when the block exits; without
|
|
38
|
+
# one, returns the process and terminate is the caller's job.
|
|
39
|
+
#
|
|
40
|
+
# @rbs command: String
|
|
41
|
+
# @rbs *args: String
|
|
42
|
+
# @rbs env: Hash[String, String]?
|
|
43
|
+
# @rbs cwd: String?
|
|
44
|
+
# @rbs stderr: (:inherit | :capture)
|
|
45
|
+
# @rbs permission: ACP::ClientConnection::_PermissionHandler
|
|
46
|
+
# @rbs updates: ACP::ClientConnection::_UpdateHandler
|
|
47
|
+
# @rbs &block: ? (ACP::ClientConnection, ACP::AgentProcess) -> untyped
|
|
48
|
+
# @rbs return: (untyped | ACP::AgentProcess)
|
|
49
|
+
def self.spawn: (String command, *String args, permission: ACP::ClientConnection::_PermissionHandler, ?env: Hash[String, String]?, ?cwd: String?, ?stderr: :inherit | :capture, ?updates: ACP::ClientConnection::_UpdateHandler) ?{ (ACP::ClientConnection, ACP::AgentProcess) -> untyped } -> (untyped | ACP::AgentProcess)
|
|
50
|
+
|
|
51
|
+
# Closes stdin, waits for the child to exit — sending TERM and then KILL if
|
|
52
|
+
# it will not — and joins the transport reader before closing the pipe it
|
|
53
|
+
# reads.
|
|
54
|
+
#
|
|
55
|
+
# @rbs return: void
|
|
56
|
+
def terminate: () -> void
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# @rbs connection: ACP::ClientConnection
|
|
61
|
+
# @rbs reader: Thread
|
|
62
|
+
# @rbs stdin: IO
|
|
63
|
+
# @rbs stdout: IO
|
|
64
|
+
# @rbs waiter: Process::Waiter
|
|
65
|
+
# @rbs err_r: IO?
|
|
66
|
+
# @rbs return: void
|
|
67
|
+
def initialize: (connection: ACP::ClientConnection, reader: Thread, stdin: IO, stdout: IO, waiter: Process::Waiter, err_r: IO?) -> void
|
|
68
|
+
|
|
69
|
+
# @rbs sig: String
|
|
70
|
+
# @rbs return: void
|
|
71
|
+
def signal: (String sig) -> void
|
|
72
|
+
end
|
|
@@ -26,26 +26,26 @@ class ACP::ClientConnection
|
|
|
26
26
|
# sent by connect.
|
|
27
27
|
#
|
|
28
28
|
# @rbs request: ACP::Types::InitializeRequest
|
|
29
|
-
# @rbs return: ACP::Types::InitializeResponse | ACP::
|
|
30
|
-
def connect: (ACP::Types::InitializeRequest request) -> (ACP::Types::InitializeResponse | ACP::
|
|
29
|
+
# @rbs return: ACP::Types::InitializeResponse | ACP::RequestError
|
|
30
|
+
def connect: (ACP::Types::InitializeRequest request) -> (ACP::Types::InitializeResponse | ACP::RequestError)
|
|
31
31
|
|
|
32
32
|
# @rbs request: ACP::Types::NewSessionRequest
|
|
33
|
-
# @rbs return: ACP::Types::NewSessionResponse | ACP::
|
|
34
|
-
def session_new: (ACP::Types::NewSessionRequest request) -> (ACP::Types::NewSessionResponse | ACP::
|
|
33
|
+
# @rbs return: ACP::Types::NewSessionResponse | ACP::RequestError
|
|
34
|
+
def session_new: (ACP::Types::NewSessionRequest request) -> (ACP::Types::NewSessionResponse | ACP::RequestError)
|
|
35
35
|
|
|
36
36
|
# @rbs request: ACP::Types::PromptRequest
|
|
37
37
|
# @rbs &block: (ACP::Types::SessionUpdate::t) -> void
|
|
38
|
-
# @rbs return: ACP::Types::PromptResponse | ACP::
|
|
39
|
-
def session_prompt: (ACP::Types::PromptRequest request) { (ACP::Types::SessionUpdate::t) -> void } -> (ACP::Types::PromptResponse | ACP::
|
|
38
|
+
# @rbs return: ACP::Types::PromptResponse | ACP::RequestError
|
|
39
|
+
def session_prompt: (ACP::Types::PromptRequest request) { (ACP::Types::SessionUpdate::t) -> void } -> (ACP::Types::PromptResponse | ACP::RequestError)
|
|
40
40
|
|
|
41
41
|
# @rbs request: ACP::Types::LoadSessionRequest
|
|
42
42
|
# @rbs &block: (ACP::Types::SessionUpdate::t) -> void
|
|
43
|
-
# @rbs return: ACP::Types::LoadSessionResponse | ACP::
|
|
44
|
-
def session_load: (ACP::Types::LoadSessionRequest request) { (ACP::Types::SessionUpdate::t) -> void } -> (ACP::Types::LoadSessionResponse | ACP::
|
|
43
|
+
# @rbs return: ACP::Types::LoadSessionResponse | ACP::RequestError
|
|
44
|
+
def session_load: (ACP::Types::LoadSessionRequest request) { (ACP::Types::SessionUpdate::t) -> void } -> (ACP::Types::LoadSessionResponse | ACP::RequestError)
|
|
45
45
|
|
|
46
46
|
# @rbs request: ACP::Types::ListSessionsRequest
|
|
47
|
-
# @rbs return: ACP::Types::ListSessionsResponse | ACP::
|
|
48
|
-
def session_list: (ACP::Types::ListSessionsRequest request) -> (ACP::Types::ListSessionsResponse | ACP::
|
|
47
|
+
# @rbs return: ACP::Types::ListSessionsResponse | ACP::RequestError
|
|
48
|
+
def session_list: (ACP::Types::ListSessionsRequest request) -> (ACP::Types::ListSessionsResponse | ACP::RequestError)
|
|
49
49
|
|
|
50
50
|
# @rbs notification: ACP::Types::CancelNotification
|
|
51
51
|
# @rbs return: void
|
|
@@ -54,9 +54,9 @@ class ACP::ClientConnection
|
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
# @rbs type: ACP::AgentConnection::_Parser
|
|
57
|
-
# @rbs result: ACP::
|
|
57
|
+
# @rbs result: (Hash[String, untyped] | ACP::RequestError)
|
|
58
58
|
# @rbs return: untyped
|
|
59
|
-
def parse: (ACP::AgentConnection::_Parser type, ACP::
|
|
59
|
+
def parse: (ACP::AgentConnection::_Parser type, Hash[String, untyped] | ACP::RequestError result) -> untyped
|
|
60
60
|
|
|
61
61
|
# The request waits on its own thread so the caller's thread can yield each
|
|
62
62
|
# update as it arrives. The reader thread queues an update before it settles
|
|
@@ -66,8 +66,8 @@ class ACP::ClientConnection
|
|
|
66
66
|
# @rbs method: String
|
|
67
67
|
# @rbs params: Hash[String, untyped]
|
|
68
68
|
# @rbs &block: (ACP::Types::SessionUpdate::t) -> void
|
|
69
|
-
# @rbs return: ACP::
|
|
70
|
-
def stream: (String session_id, String method, Hash[String, untyped] params) { (ACP::Types::SessionUpdate::t) -> void } -> ACP::
|
|
69
|
+
# @rbs return: (Hash[String, untyped] | ACP::RequestError)
|
|
70
|
+
def stream: (String session_id, String method, Hash[String, untyped] params) { (ACP::Types::SessionUpdate::t) -> void } -> (Hash[String, untyped] | ACP::RequestError)
|
|
71
71
|
|
|
72
72
|
# Pushes under the lock so a stream cannot close its queue between the
|
|
73
73
|
# lookup and the push.
|
|
@@ -77,6 +77,6 @@ class ACP::ClientConnection
|
|
|
77
77
|
def dispatch: (untyped params) -> void
|
|
78
78
|
|
|
79
79
|
# @rbs params: untyped
|
|
80
|
-
# @rbs return: ACP::
|
|
81
|
-
def request_permission: (untyped params) -> ACP::
|
|
80
|
+
# @rbs return: (ACP::Types::RequestPermissionResponse | ACP::RequestError)
|
|
81
|
+
def request_permission: (untyped params) -> (ACP::Types::RequestPermissionResponse | ACP::RequestError)
|
|
82
82
|
end
|