AcpSyncAgent agent = AcpAgent.sync(transport)
.initializeHandler(req -> InitializeResponse.ok())
.newSessionHandler(req -> {
String sessionId = "sess-" + UUID.randomUUID().toString().substring(0, 8);
sessions.put(sessionId, new SessionState(
req.cwd(), null, Instant.now(), new ArrayList<>()));
return new NewSessionResponse(sessionId, null, null);
})
// Return SessionInfo metadata, honoring the optional cwd filter
.listSessionsHandler(req -> {
List<SessionInfo> infos = new ArrayList<>();
for (var entry : sessions.entrySet()) {
SessionState state = entry.getValue();
if (req.cwd() != null && !req.cwd().equals(state.cwd())) {
continue;
}
infos.add(new SessionInfo(
entry.getKey(),
state.cwd(),
"Session with " + state.messages().size() + " messages",
state.createdAt().toString(),
null,
null));
}
return new ListSessionsResponse(infos);
})
// Unlike loadSession, resumeSession sends no session/update notifications
.resumeSessionHandler(req -> {
sessions.putIfAbsent(req.sessionId(), new SessionState(
req.cwd(), null, Instant.now(), new ArrayList<>()));
return new ResumeSessionResponse(null, null);
})
.closeSessionHandler(req -> {
sessions.remove(req.sessionId());
return new CloseSessionResponse();
})
.promptHandler((req, context) -> {
SessionState state = sessions.get(req.sessionId());
if (state != null) {
state.messages().add(req.text());
}
context.sendMessage("Active sessions: " + sessions.size() + "\n"
+ "You said: " + req.text() + "\n");
return PromptResponse.endTurn();
})
.build();