acp-sdk 0.2.0 → 0.3.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 +8 -0
- data/README.md +28 -15
- data/lib/acp/agent_connection/client.rb +25 -12
- data/lib/acp/agent_connection.rb +18 -31
- data/lib/acp/agent_process.rb +119 -0
- data/lib/acp/client_connection.rb +13 -15
- data/lib/acp/request_error.rb +81 -0
- data/lib/acp/transport/reply.rb +4 -4
- data/lib/acp/transport/stdio.rb +28 -25
- data/lib/acp/version.rb +1 -1
- data/sig/generated/acp/agent_connection/client.rbs +23 -16
- 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 +65 -0
- data/sig/generated/acp/transport/reply.rbs +5 -5
- data/sig/generated/acp/transport/stdio.rbs +14 -19
- data/sig/manual/acp/agent_connection.rbs +19 -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 +6 -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)
|
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
|
|
@@ -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
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Generated from lib/acp/request_error.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# The schema's JSON-RPC Error object, named after the official SDKs'
|
|
4
|
+
# RequestError: built by handlers and local refusals, and decoded from a
|
|
5
|
+
# peer's error replies by the transport.
|
|
6
|
+
class ACP::RequestError
|
|
7
|
+
PARSE_ERROR: Integer
|
|
8
|
+
|
|
9
|
+
INVALID_REQUEST: Integer
|
|
10
|
+
|
|
11
|
+
METHOD_NOT_FOUND: Integer
|
|
12
|
+
|
|
13
|
+
INVALID_PARAMS: Integer
|
|
14
|
+
|
|
15
|
+
INTERNAL_ERROR: Integer
|
|
16
|
+
|
|
17
|
+
REQUEST_CANCELLED: Integer
|
|
18
|
+
|
|
19
|
+
AUTH_REQUIRED: Integer
|
|
20
|
+
|
|
21
|
+
RESOURCE_NOT_FOUND: Integer
|
|
22
|
+
|
|
23
|
+
# @rbs code: Integer
|
|
24
|
+
# @rbs message: String
|
|
25
|
+
# @rbs data: untyped
|
|
26
|
+
# @rbs return: void
|
|
27
|
+
def initialize: (code: Integer, message: String, ?data: untyped) -> void
|
|
28
|
+
|
|
29
|
+
# @dynamic code
|
|
30
|
+
attr_reader code: Integer
|
|
31
|
+
|
|
32
|
+
# @dynamic message
|
|
33
|
+
attr_reader message: String
|
|
34
|
+
|
|
35
|
+
# @dynamic data
|
|
36
|
+
attr_reader data: untyped
|
|
37
|
+
|
|
38
|
+
# @rbs return: Hash[String, untyped]
|
|
39
|
+
def to_h: () -> Hash[String, untyped]
|
|
40
|
+
|
|
41
|
+
# @rbs return: ACP::RequestError
|
|
42
|
+
def self.parse_error: () -> ACP::RequestError
|
|
43
|
+
|
|
44
|
+
# @rbs return: ACP::RequestError
|
|
45
|
+
def self.invalid_request: () -> ACP::RequestError
|
|
46
|
+
|
|
47
|
+
# @rbs return: ACP::RequestError
|
|
48
|
+
def self.method_not_found: () -> ACP::RequestError
|
|
49
|
+
|
|
50
|
+
# @rbs return: ACP::RequestError
|
|
51
|
+
def self.invalid_params: () -> ACP::RequestError
|
|
52
|
+
|
|
53
|
+
# @rbs return: ACP::RequestError
|
|
54
|
+
def self.internal_error: () -> ACP::RequestError
|
|
55
|
+
|
|
56
|
+
# @rbs return: ACP::RequestError
|
|
57
|
+
def self.request_cancelled: () -> ACP::RequestError
|
|
58
|
+
|
|
59
|
+
# @rbs return: ACP::RequestError
|
|
60
|
+
def self.auth_required: () -> ACP::RequestError
|
|
61
|
+
|
|
62
|
+
# @rbs uri: String?
|
|
63
|
+
# @rbs return: ACP::RequestError
|
|
64
|
+
def self.resource_not_found: (?String? uri) -> ACP::RequestError
|
|
65
|
+
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# Generated from lib/acp/transport/reply.rb with RBS::Inline
|
|
2
2
|
|
|
3
|
-
# A request handler's
|
|
4
|
-
#
|
|
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
5
|
class ACP::Transport::Reply
|
|
6
6
|
# @dynamic result
|
|
7
|
-
attr_reader result: ACP::Transport::
|
|
7
|
+
attr_reader result: ACP::Transport::Stdio::_ToH
|
|
8
8
|
|
|
9
9
|
# @dynamic after
|
|
10
10
|
attr_reader after: ^() -> void
|
|
11
11
|
|
|
12
|
-
# @rbs result: ACP::Transport::
|
|
12
|
+
# @rbs result: ACP::Transport::Stdio::_ToH
|
|
13
13
|
# @rbs after: ^() -> void
|
|
14
14
|
# @rbs return: void
|
|
15
|
-
def initialize: (ACP::Transport::
|
|
15
|
+
def initialize: (ACP::Transport::Stdio::_ToH result, after: ^() -> void) -> void
|
|
16
16
|
end
|
|
@@ -20,15 +20,7 @@ class ACP::Transport::Stdio
|
|
|
20
20
|
|
|
21
21
|
@input: _Reader
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
PARSE_ERROR: ACP::Transport::ResponseError
|
|
26
|
-
|
|
27
|
-
INVALID_REQUEST: ACP::Transport::ResponseError
|
|
28
|
-
|
|
29
|
-
METHOD_NOT_FOUND: ACP::Transport::ResponseError
|
|
30
|
-
|
|
31
|
-
CONNECTION_CLOSED: ACP::Transport::ResponseError
|
|
23
|
+
CONNECTION_CLOSED: ACP::RequestError
|
|
32
24
|
|
|
33
25
|
# @rbs input: _Reader
|
|
34
26
|
# @rbs output: _Writer
|
|
@@ -45,8 +37,8 @@ class ACP::Transport::Stdio
|
|
|
45
37
|
|
|
46
38
|
# @rbs method: String
|
|
47
39
|
# @rbs params: untyped
|
|
48
|
-
# @rbs return: ACP::
|
|
49
|
-
def request: (String method, ?untyped params) -> ACP::
|
|
40
|
+
# @rbs return: (Hash[String, untyped] | ACP::RequestError)
|
|
41
|
+
def request: (String method, ?untyped params) -> (Hash[String, untyped] | ACP::RequestError)
|
|
50
42
|
|
|
51
43
|
# @rbs method: String
|
|
52
44
|
# @rbs params: untyped
|
|
@@ -68,8 +60,8 @@ class ACP::Transport::Stdio
|
|
|
68
60
|
def route: (Hash[String, untyped] message, Hash[String, _Handler] requests, Hash[String, _NotificationHandler] notifications) -> void
|
|
69
61
|
|
|
70
62
|
# @rbs line: String
|
|
71
|
-
# @rbs return: Hash[String, untyped] | ACP::
|
|
72
|
-
def parse: (String line) -> (Hash[String, untyped] | ACP::
|
|
63
|
+
# @rbs return: Hash[String, untyped] | ACP::RequestError
|
|
64
|
+
def parse: (String line) -> (Hash[String, untyped] | ACP::RequestError)
|
|
73
65
|
|
|
74
66
|
# @rbs handler: _Handler?
|
|
75
67
|
# @rbs id: untyped
|
|
@@ -90,22 +82,25 @@ class ACP::Transport::Stdio
|
|
|
90
82
|
#
|
|
91
83
|
# @rbs handler: _Handler
|
|
92
84
|
# @rbs params: untyped
|
|
93
|
-
# @rbs return: ACP::
|
|
94
|
-
def invoke: (_Handler handler, untyped params) -> (ACP::
|
|
85
|
+
# @rbs return: (_ToH | ACP::RequestError | ACP::Transport::Reply)
|
|
86
|
+
def invoke: (_Handler handler, untyped params) -> (_ToH | ACP::RequestError | ACP::Transport::Reply)
|
|
95
87
|
|
|
88
|
+
# The success arm is whatever the handler returned, which the transport only
|
|
89
|
+
# knows serializes with to_h; RequestError picks the error arm of the reply.
|
|
90
|
+
#
|
|
96
91
|
# @rbs id: untyped
|
|
97
|
-
# @rbs
|
|
92
|
+
# @rbs outcome: (_ToH | ACP::RequestError)
|
|
98
93
|
# @rbs return: void
|
|
99
|
-
def reply: (untyped id, ACP::
|
|
94
|
+
def reply: (untyped id, _ToH | ACP::RequestError outcome) -> void
|
|
100
95
|
|
|
101
96
|
# @rbs queue: Thread::Queue
|
|
102
97
|
# @rbs return: Integer?
|
|
103
98
|
def register: (Thread::Queue queue) -> Integer?
|
|
104
99
|
|
|
105
100
|
# @rbs id: untyped
|
|
106
|
-
# @rbs result: ACP::
|
|
101
|
+
# @rbs result: (Hash[String, untyped] | ACP::RequestError)
|
|
107
102
|
# @rbs return: void
|
|
108
|
-
def settle: (untyped id, ACP::
|
|
103
|
+
def settle: (untyped id, Hash[String, untyped] | ACP::RequestError result) -> void
|
|
109
104
|
|
|
110
105
|
# @rbs return: void
|
|
111
106
|
def close: () -> void
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class ACP::AgentConnection
|
|
2
2
|
interface _Agent
|
|
3
|
-
def new_session: (ACP::Types::NewSessionRequest) -> (ACP::Types::NewSessionResponse | ACP::
|
|
4
|
-
def prompt: (ACP::Types::PromptRequest) -> (ACP::Types::PromptResponse | ACP::
|
|
3
|
+
def new_session: (ACP::Types::NewSessionRequest) -> (ACP::Types::NewSessionResponse | ACP::RequestError)
|
|
4
|
+
def prompt: (ACP::Types::PromptRequest) -> (ACP::Types::PromptResponse | ACP::RequestError)
|
|
5
5
|
# Runs on the transport's reader thread, so it must return quickly.
|
|
6
6
|
def cancel: (ACP::Types::CancelNotification) -> void
|
|
7
7
|
# AgentConnection probes for the optional methods below.
|
|
@@ -9,35 +9,35 @@ class ACP::AgentConnection
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
interface _LoadSession
|
|
12
|
-
def load_session: (ACP::Types::LoadSessionRequest) -> (ACP::Types::LoadSessionResponse | ACP::
|
|
12
|
+
def load_session: (ACP::Types::LoadSessionRequest) -> (ACP::Types::LoadSessionResponse | ACP::RequestError)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
interface _ListSessions
|
|
16
|
-
def list_sessions: (ACP::Types::ListSessionsRequest) -> (ACP::Types::ListSessionsResponse | ACP::
|
|
16
|
+
def list_sessions: (ACP::Types::ListSessionsRequest) -> (ACP::Types::ListSessionsResponse | ACP::RequestError)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
interface _Authenticate
|
|
20
|
-
def authenticate: (ACP::Types::AuthenticateRequest) -> (ACP::Types::AuthenticateResponse | ACP::
|
|
20
|
+
def authenticate: (ACP::Types::AuthenticateRequest) -> (ACP::Types::AuthenticateResponse | ACP::RequestError)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
interface _ResumeSession
|
|
24
|
-
def resume_session: (ACP::Types::ResumeSessionRequest) -> (ACP::Types::ResumeSessionResponse | ACP::
|
|
24
|
+
def resume_session: (ACP::Types::ResumeSessionRequest) -> (ACP::Types::ResumeSessionResponse | ACP::RequestError)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
interface _CloseSession
|
|
28
|
-
def close_session: (ACP::Types::CloseSessionRequest) -> (ACP::Types::CloseSessionResponse | ACP::
|
|
28
|
+
def close_session: (ACP::Types::CloseSessionRequest) -> (ACP::Types::CloseSessionResponse | ACP::RequestError)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
interface _DeleteSession
|
|
32
|
-
def delete_session: (ACP::Types::DeleteSessionRequest) -> (ACP::Types::DeleteSessionResponse | ACP::
|
|
32
|
+
def delete_session: (ACP::Types::DeleteSessionRequest) -> (ACP::Types::DeleteSessionResponse | ACP::RequestError)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
interface _ChangeSessionMode
|
|
36
|
-
def change_session_mode: (ACP::Types::SetSessionModeRequest) -> (ACP::Types::SetSessionModeResponse | ACP::
|
|
36
|
+
def change_session_mode: (ACP::Types::SetSessionModeRequest) -> (ACP::Types::SetSessionModeResponse | ACP::RequestError)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
interface _ChangeSessionConfigOption
|
|
40
|
-
def change_session_config_option: (ACP::Types::SetSessionConfigOptionRequest) -> (ACP::Types::SetSessionConfigOptionResponse | ACP::
|
|
40
|
+
def change_session_config_option: (ACP::Types::SetSessionConfigOptionRequest) -> (ACP::Types::SetSessionConfigOptionResponse | ACP::RequestError)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
interface _FullAgent
|
|
@@ -66,19 +66,19 @@ class ACP::AgentConnection
|
|
|
66
66
|
interface _Client
|
|
67
67
|
def update: (String session_id, ACP::Types::SessionUpdate::t update) -> void
|
|
68
68
|
def available_commands: (String session_id, Array[ACP::Types::AvailableCommand] commands) -> void
|
|
69
|
-
def request_permission: (ACP::Types::RequestPermissionRequest) -> (ACP::Types::RequestPermissionResponse | ACP::
|
|
70
|
-
def read_text_file: (ACP::Types::ReadTextFileRequest) -> (ACP::Types::ReadTextFileResponse | ACP::
|
|
71
|
-
def write_text_file: (ACP::Types::WriteTextFileRequest) -> (ACP::Types::WriteTextFileResponse | ACP::
|
|
72
|
-
def create_terminal: (ACP::Types::CreateTerminalRequest) -> (ACP::Types::CreateTerminalResponse | ACP::
|
|
73
|
-
def terminal_output: (ACP::Types::TerminalOutputRequest) -> (ACP::Types::TerminalOutputResponse | ACP::
|
|
74
|
-
def wait_for_terminal_exit: (ACP::Types::WaitForTerminalExitRequest) -> (ACP::Types::WaitForTerminalExitResponse | ACP::
|
|
75
|
-
def kill_terminal: (ACP::Types::KillTerminalRequest) -> (ACP::Types::KillTerminalResponse | ACP::
|
|
76
|
-
def release_terminal: (ACP::Types::ReleaseTerminalRequest) -> (ACP::Types::ReleaseTerminalResponse | ACP::
|
|
69
|
+
def request_permission: (ACP::Types::RequestPermissionRequest) -> (ACP::Types::RequestPermissionResponse | ACP::RequestError)
|
|
70
|
+
def read_text_file: (ACP::Types::ReadTextFileRequest) -> (ACP::Types::ReadTextFileResponse | ACP::RequestError)
|
|
71
|
+
def write_text_file: (ACP::Types::WriteTextFileRequest) -> (ACP::Types::WriteTextFileResponse | ACP::RequestError)
|
|
72
|
+
def create_terminal: (ACP::Types::CreateTerminalRequest) -> (ACP::Types::CreateTerminalResponse | ACP::RequestError)
|
|
73
|
+
def terminal_output: (ACP::Types::TerminalOutputRequest) -> (ACP::Types::TerminalOutputResponse | ACP::RequestError)
|
|
74
|
+
def wait_for_terminal_exit: (ACP::Types::WaitForTerminalExitRequest) -> (ACP::Types::WaitForTerminalExitResponse | ACP::RequestError)
|
|
75
|
+
def kill_terminal: (ACP::Types::KillTerminalRequest) -> (ACP::Types::KillTerminalResponse | ACP::RequestError)
|
|
76
|
+
def release_terminal: (ACP::Types::ReleaseTerminalRequest) -> (ACP::Types::ReleaseTerminalResponse | ACP::RequestError)
|
|
77
77
|
def capabilities: () -> ACP::Types::ClientCapabilities?
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
interface _Peer
|
|
81
|
-
def request: (String method, ?untyped params) -> ACP::
|
|
81
|
+
def request: (String method, ?untyped params) -> (Hash[String, untyped] | ACP::RequestError)
|
|
82
82
|
def notify: (String method, ?untyped params) -> void
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class ACP::ClientConnection
|
|
2
2
|
interface _PermissionHandler
|
|
3
3
|
# Runs on its own thread, so it may block while the user decides.
|
|
4
|
-
def call: (ACP::Types::RequestPermissionRequest) -> (ACP::Types::RequestPermissionResponse | ACP::
|
|
4
|
+
def call: (ACP::Types::RequestPermissionRequest) -> (ACP::Types::RequestPermissionResponse | ACP::RequestError)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
# Receives the session/update notifications that arrive outside a
|