Skip to content

Commit 721948c

Browse files
committed
Error handle.
1 parent 163841c commit 721948c

6 files changed

Lines changed: 214 additions & 101 deletions

File tree

src/tools/ecode/plugins/aiassistant/acp/acpclient.cpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ void ACPClient::processResponse( const json& msg ) {
152152

153153
if ( handler ) {
154154
handler( id, msg );
155+
} else if ( msg.contains( "error" ) && onError ) {
156+
onError( ResponseError( msg["error"] ) );
155157
}
156158
}
157159

@@ -194,54 +196,74 @@ void ACPClient::sendError( const json& id, int code, const std::string& message
194196
}
195197
}
196198

197-
void ACPClient::initialize( const InitializeRequest& req,
198-
const std::function<void( const InitializeResponse& )>& cb ) {
199+
void ACPClient::initialize(
200+
const InitializeRequest& req,
201+
const std::function<void( const InitializeResponse&, const std::optional<ResponseError>& )>&
202+
cb ) {
199203
write( { { "method", "initialize" }, { "params", req.toJson() } },
200204
[this, cb]( const IdType&, const json& resp ) {
201205
if ( resp.contains( "result" ) ) {
202206
mReady = true;
203207
if ( cb )
204-
cb( InitializeResponse( resp["result"] ) );
208+
cb( InitializeResponse( resp["result"] ), std::nullopt );
209+
} else if ( resp.contains( "error" ) ) {
210+
if ( cb )
211+
cb( {}, ResponseError( resp["error"] ) );
205212
}
206213
} );
207214
}
208215

209-
void ACPClient::newSession( const NewSessionRequest& req,
210-
const std::function<void( const NewSessionResponse& )>& cb ) {
216+
void ACPClient::newSession(
217+
const NewSessionRequest& req,
218+
const std::function<void( const NewSessionResponse&, const std::optional<ResponseError>& )>&
219+
cb ) {
211220
write( { { "method", "session/new" }, { "params", req.toJson() } },
212221
[cb]( const IdType&, const json& resp ) {
213222
if ( resp.contains( "result" ) && cb ) {
214-
cb( NewSessionResponse( resp["result"] ) );
223+
cb( NewSessionResponse( resp["result"] ), std::nullopt );
224+
} else if ( resp.contains( "error" ) && cb ) {
225+
cb( {}, ResponseError( resp["error"] ) );
215226
}
216227
} );
217228
}
218229

219-
void ACPClient::loadSession( const LoadSessionRequest& req,
220-
const std::function<void( const LoadSessionResponse& )>& cb ) {
230+
void ACPClient::loadSession(
231+
const LoadSessionRequest& req,
232+
const std::function<void( const LoadSessionResponse&, const std::optional<ResponseError>& )>&
233+
cb ) {
221234
write( { { "method", "session/load" }, { "params", req.toJson() } },
222235
[cb]( const IdType&, const json& resp ) {
223236
if ( resp.contains( "result" ) && cb ) {
224-
cb( LoadSessionResponse( resp["result"] ) );
237+
cb( LoadSessionResponse( resp["result"] ), std::nullopt );
238+
} else if ( resp.contains( "error" ) && cb ) {
239+
cb( {}, ResponseError( resp["error"] ) );
225240
}
226241
} );
227242
}
228243

229-
void ACPClient::listSessions( const ListSessionsRequest& req,
230-
const std::function<void( const ListSessionsResponse& )>& cb ) {
244+
void ACPClient::listSessions(
245+
const ListSessionsRequest& req,
246+
const std::function<void( const ListSessionsResponse&, const std::optional<ResponseError>& )>&
247+
cb ) {
231248
write( { { "method", "session/list" }, { "params", req.toJson() } },
232249
[cb]( const IdType&, const json& resp ) {
233250
if ( resp.contains( "result" ) && cb ) {
234-
cb( ListSessionsResponse( resp["result"] ) );
251+
cb( ListSessionsResponse( resp["result"] ), std::nullopt );
252+
} else if ( resp.contains( "error" ) && cb ) {
253+
cb( {}, ResponseError( resp["error"] ) );
235254
}
236255
} );
237256
}
238257

239-
void ACPClient::prompt( const PromptRequest& req,
240-
const std::function<void( const PromptResponse& )>& cb ) {
258+
void ACPClient::prompt(
259+
const PromptRequest& req,
260+
const std::function<void( const PromptResponse&, const std::optional<ResponseError>& )>& cb ) {
241261
write( { { "method", "session/prompt" }, { "params", req.toJson() } },
242262
[cb]( const IdType&, const json& resp ) {
243263
if ( resp.contains( "result" ) && cb ) {
244-
cb( PromptResponse( resp["result"] ) );
264+
cb( PromptResponse( resp["result"] ), std::nullopt );
265+
} else if ( resp.contains( "error" ) && cb ) {
266+
cb( {}, ResponseError( resp["error"] ) );
245267
}
246268
} );
247269
}

src/tools/ecode/plugins/aiassistant/acp/acpclient.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,26 @@ class ACPClient {
4444
const Config& getConfig() const { return mConfig; }
4545

4646
void initialize( const InitializeRequest& req,
47-
const std::function<void( const InitializeResponse& )>& cb );
47+
const std::function<void( const InitializeResponse&,
48+
const std::optional<ResponseError>& )>& cb );
4849
void newSession( const NewSessionRequest& req,
49-
const std::function<void( const NewSessionResponse& )>& cb );
50+
const std::function<void( const NewSessionResponse&,
51+
const std::optional<ResponseError>& )>& cb );
5052
void loadSession( const LoadSessionRequest& req,
51-
const std::function<void( const LoadSessionResponse& )>& cb );
53+
const std::function<void( const LoadSessionResponse&,
54+
const std::optional<ResponseError>& )>& cb );
5255
void listSessions( const ListSessionsRequest& req,
53-
const std::function<void( const ListSessionsResponse& )>& cb );
54-
void prompt( const PromptRequest& req, const std::function<void( const PromptResponse& )>& cb );
56+
const std::function<void( const ListSessionsResponse&,
57+
const std::optional<ResponseError>& )>& cb );
58+
void prompt( const PromptRequest& req,
59+
const std::function<void( const PromptResponse&,
60+
const std::optional<ResponseError>& )>& cb );
5561

5662
// Notifications to agent
5763
void cancel( const std::string& sessionId );
5864

5965
// Callbacks from agent
66+
std::function<void( const ResponseError& )> onError;
6067
std::function<void( const json& )> onSessionUpdate;
6168
std::function<void( const ReadTextFileRequest&,
6269
std::function<void( const ReadTextFileResponse& )> )>

src/tools/ecode/plugins/aiassistant/acp/acpprotocol.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,22 @@ struct ListSessionsResponse {
105105
ListSessionsResponse( const json& body );
106106
};
107107

108+
struct ResponseError {
109+
int code{ 0 };
110+
std::string message;
111+
json data;
112+
113+
ResponseError() = default;
114+
ResponseError( const json& body ) {
115+
if ( body.contains( "code" ) )
116+
code = body["code"].get<int>();
117+
if ( body.contains( "message" ) )
118+
message = body["message"].get<std::string>();
119+
if ( body.contains( "data" ) )
120+
data = body["data"];
121+
}
122+
};
123+
108124
struct PromptRequest {
109125
std::string sessionId;
110126
json prompt; // Array of ContentBlock

src/tools/ecode/plugins/aiassistant/acp/agentsession.cpp

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,28 @@ bool AgentSession::start( const std::function<void( bool )>& onReady ) {
2121
req.clientCapabilities.fsReadTextFile = true;
2222
req.clientCapabilities.fsWriteTextFile = true;
2323

24-
mClient->initialize( req, [this, onReady]( const InitializeResponse& ) {
25-
NewSessionRequest nreq;
26-
nreq.cwd = mClient->isReady() ? mClient->getConfig().workingDirectory : "";
27-
mClient->newSession( nreq, [this, onReady]( const NewSessionResponse& nres ) {
28-
mSessionId = nres.sessionId;
29-
if ( onReady )
30-
onReady( true );
24+
mClient->initialize(
25+
req, [this, onReady]( const InitializeResponse&, const std::optional<ResponseError>& err ) {
26+
if ( err ) {
27+
if ( onReady )
28+
onReady( false );
29+
return;
30+
}
31+
NewSessionRequest nreq;
32+
nreq.cwd = mClient->isReady() ? mClient->getConfig().workingDirectory : "";
33+
mClient->newSession(
34+
nreq, [this, onReady]( const NewSessionResponse& nres,
35+
const std::optional<ResponseError>& err ) {
36+
if ( err ) {
37+
if ( onReady )
38+
onReady( false );
39+
return;
40+
}
41+
mSessionId = nres.sessionId;
42+
if ( onReady )
43+
onReady( true );
44+
} );
3145
} );
32-
} );
3346
return true;
3447
}
3548
if ( onReady )
@@ -45,55 +58,74 @@ bool AgentSession::startLoaded( const std::string& sessionId,
4558
req.clientCapabilities.fsReadTextFile = true;
4659
req.clientCapabilities.fsWriteTextFile = true;
4760

48-
mClient->initialize( req, [this, sessionId, onReady]( const InitializeResponse& ires ) {
49-
if ( ires.agentCapabilities.loadSession ) {
50-
LoadSessionRequest lreq;
51-
lreq.sessionId = sessionId;
52-
lreq.cwd = mClient->isReady() ? mClient->getConfig().workingDirectory : "";
53-
mClient->loadSession( lreq, [this, sessionId, onReady]( const LoadSessionResponse& ) {
54-
mSessionId = sessionId;
61+
mClient->initialize(
62+
req, [this, sessionId, onReady]( const InitializeResponse& ires,
63+
const std::optional<ResponseError>& err ) {
64+
if ( err ) {
5565
if ( onReady )
56-
onReady( true );
57-
} );
58-
} else {
59-
// Agent doesn't support loading, fallback to new session?
60-
// For now let's just fail or call onReady(false)
61-
if ( onReady )
62-
onReady( false );
63-
}
64-
} );
66+
onReady( false );
67+
return;
68+
}
69+
if ( ires.agentCapabilities.loadSession ) {
70+
LoadSessionRequest lreq;
71+
lreq.sessionId = sessionId;
72+
lreq.cwd = mClient->isReady() ? mClient->getConfig().workingDirectory : "";
73+
mClient->loadSession(
74+
lreq, [this, sessionId, onReady]( const LoadSessionResponse&,
75+
const std::optional<ResponseError>& err ) {
76+
if ( err ) {
77+
if ( onReady )
78+
onReady( false );
79+
return;
80+
}
81+
mSessionId = sessionId;
82+
if ( onReady )
83+
onReady( true );
84+
} );
85+
} else {
86+
if ( onReady )
87+
onReady( false );
88+
}
89+
} );
6590
return true;
6691
}
6792
if ( onReady )
6893
onReady( false );
6994
return false;
7095
}
7196

72-
void AgentSession::listSessions( const std::function<void( const std::vector<SessionInfo>& )>& cb ) {
97+
void AgentSession::listSessions(
98+
const std::function<void( const std::vector<SessionInfo>&, const std::optional<ResponseError>& )>&
99+
cb ) {
73100
if ( !mClient->isReady() ) {
74-
if ( cb ) cb( {} );
101+
if ( cb )
102+
cb( {}, std::nullopt );
75103
return;
76104
}
77105
ListSessionsRequest req;
78106
req.cwd = mClient->getConfig().workingDirectory;
79-
mClient->listSessions( req, [cb]( const ListSessionsResponse& res ) {
80-
if ( cb ) cb( res.sessions );
81-
} );
107+
mClient->listSessions(
108+
req, [cb]( const ListSessionsResponse& res, const std::optional<ResponseError>& err ) {
109+
if ( cb )
110+
cb( res.sessions, err );
111+
} );
82112
}
83113

84114
void AgentSession::stop() {
85115
if ( mClient )
86116
mClient->stop();
87117
}
88118

89-
void AgentSession::prompt( const PromptRequest& req,
90-
const std::function<void( const PromptResponse& )>& cb ) {
119+
void AgentSession::prompt(
120+
const PromptRequest& req,
121+
const std::function<void( const PromptResponse&, const std::optional<ResponseError>& )>& cb ) {
91122
mIsPrompting = true;
92-
mClient->prompt( req, [this, cb](const PromptResponse& res) {
93-
mIsPrompting = false;
94-
if ( cb )
95-
cb(res);
96-
} );
123+
mClient->prompt(
124+
req, [this, cb]( const PromptResponse& res, const std::optional<ResponseError>& err ) {
125+
mIsPrompting = false;
126+
if ( cb )
127+
cb( res, err );
128+
} );
97129
}
98130

99131
void AgentSession::cancel() {
@@ -108,6 +140,11 @@ void AgentSession::setTerminalData( const std::string& terminalId, UITerminal* u
108140
}
109141

110142
void AgentSession::setupClient() {
143+
mClient->onError = [this]( const ResponseError& err ) {
144+
if ( onError )
145+
onError( err );
146+
};
147+
111148
mClient->onSessionUpdate = [this]( const json& msg ) {
112149
if ( onSessionUpdate )
113150
onSessionUpdate( msg );

src/tools/ecode/plugins/aiassistant/acp/agentsession.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,19 @@ class AgentSession {
2222

2323
bool start( const std::function<void( bool )>& onReady );
2424
bool startLoaded( const std::string& sessionId, const std::function<void( bool )>& onReady );
25-
void listSessions( const std::function<void( const std::vector<SessionInfo>& )>& cb );
25+
void listSessions(
26+
const std::function<void( const std::vector<SessionInfo>&, const std::optional<ResponseError>& )>&
27+
cb );
2628
void stop();
2729

28-
void prompt( const PromptRequest& req, const std::function<void( const PromptResponse& )>& cb );
30+
void prompt( const PromptRequest& req,
31+
const std::function<void( const PromptResponse&, const std::optional<ResponseError>& )>&
32+
cb );
2933
void cancel();
3034

3135
bool isPrompting() const { return mIsPrompting; }
3236

37+
std::function<void( const ResponseError& )> onError;
3338
std::function<void( const json& )> onSessionUpdate;
3439
std::function<void( const RequestPermissionRequest&,
3540
std::function<void( const RequestPermissionResponse& )> )>

0 commit comments

Comments
 (0)