|
20 | 20 | import com.github.copilot.sdk.events.SessionEventParser; |
21 | 21 | import com.github.copilot.sdk.json.PermissionRequestResult; |
22 | 22 | import com.github.copilot.sdk.json.PermissionRequestResultKind; |
| 23 | +import com.github.copilot.sdk.json.SessionFsAppendFileParams; |
| 24 | +import com.github.copilot.sdk.json.SessionFsCopyDirParams; |
| 25 | +import com.github.copilot.sdk.json.SessionFsCpParams; |
| 26 | +import com.github.copilot.sdk.json.SessionFsExistsParams; |
| 27 | +import com.github.copilot.sdk.json.SessionFsGlobParams; |
| 28 | +import com.github.copilot.sdk.json.SessionFsHandler; |
| 29 | +import com.github.copilot.sdk.json.SessionFsMkdirParams; |
| 30 | +import com.github.copilot.sdk.json.SessionFsReaddirParams; |
| 31 | +import com.github.copilot.sdk.json.SessionFsReadFileParams; |
| 32 | +import com.github.copilot.sdk.json.SessionFsRenameParams; |
| 33 | +import com.github.copilot.sdk.json.SessionFsRmParams; |
| 34 | +import com.github.copilot.sdk.json.SessionFsStatParams; |
| 35 | +import com.github.copilot.sdk.json.SessionFsWriteFileParams; |
23 | 36 | import com.github.copilot.sdk.json.SessionLifecycleEvent; |
24 | 37 | import com.github.copilot.sdk.json.SessionLifecycleEventMetadata; |
25 | 38 | import com.github.copilot.sdk.json.ToolDefinition; |
@@ -83,6 +96,32 @@ void registerHandlers(JsonRpcClient rpc) { |
83 | 96 | rpc.registerMethodHandler("hooks.invoke", (requestId, params) -> handleHooksInvoke(rpc, requestId, params)); |
84 | 97 | rpc.registerMethodHandler("systemMessage.transform", |
85 | 98 | (requestId, params) -> handleSystemMessageTransform(rpc, requestId, params)); |
| 99 | + rpc.registerMethodHandler("sessionFs.readFile", (requestId, params) -> handleSessionFsCall(rpc, requestId, |
| 100 | + params, "readFile", SessionFsReadFileParams.class, (h, p) -> h.readFile(p))); |
| 101 | + rpc.registerMethodHandler("sessionFs.writeFile", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, |
| 102 | + params, "writeFile", SessionFsWriteFileParams.class, (h, p) -> h.writeFile(p))); |
| 103 | + rpc.registerMethodHandler("sessionFs.appendFile", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, |
| 104 | + params, "appendFile", SessionFsAppendFileParams.class, (h, p) -> h.appendFile(p))); |
| 105 | + rpc.registerMethodHandler("sessionFs.exists", (requestId, params) -> handleSessionFsCall(rpc, requestId, params, |
| 106 | + "exists", SessionFsExistsParams.class, (h, p) -> h.exists(p))); |
| 107 | + rpc.registerMethodHandler("sessionFs.stat", (requestId, params) -> handleSessionFsCall(rpc, requestId, params, |
| 108 | + "stat", SessionFsStatParams.class, (h, p) -> h.stat(p))); |
| 109 | + rpc.registerMethodHandler("sessionFs.mkdir", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, |
| 110 | + params, "mkdir", SessionFsMkdirParams.class, (h, p) -> h.mkdir(p))); |
| 111 | + rpc.registerMethodHandler("sessionFs.readdir", (requestId, params) -> handleSessionFsCall(rpc, requestId, |
| 112 | + params, "readdir", SessionFsReaddirParams.class, (h, p) -> h.readdir(p))); |
| 113 | + rpc.registerMethodHandler("sessionFs.readdirWithTypes", (requestId, params) -> handleSessionFsCall(rpc, |
| 114 | + requestId, params, "readdirWithTypes", SessionFsReaddirParams.class, (h, p) -> h.readdirWithTypes(p))); |
| 115 | + rpc.registerMethodHandler("sessionFs.rm", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, params, |
| 116 | + "rm", SessionFsRmParams.class, (h, p) -> h.rm(p))); |
| 117 | + rpc.registerMethodHandler("sessionFs.rename", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, |
| 118 | + params, "rename", SessionFsRenameParams.class, (h, p) -> h.rename(p))); |
| 119 | + rpc.registerMethodHandler("sessionFs.cp", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, params, |
| 120 | + "cp", SessionFsCpParams.class, (h, p) -> h.cp(p))); |
| 121 | + rpc.registerMethodHandler("sessionFs.copyDir", (requestId, params) -> handleSessionFsVoidCall(rpc, requestId, |
| 122 | + params, "copyDir", SessionFsCopyDirParams.class, (h, p) -> h.copyDir(p))); |
| 123 | + rpc.registerMethodHandler("sessionFs.glob", (requestId, params) -> handleSessionFsCall(rpc, requestId, params, |
| 124 | + "glob", SessionFsGlobParams.class, (h, p) -> h.glob(p))); |
86 | 125 | } |
87 | 126 |
|
88 | 127 | private void handleSessionEvent(JsonNode params) { |
@@ -379,4 +418,57 @@ private void runAsync(Runnable task) { |
379 | 418 | task.run(); |
380 | 419 | } |
381 | 420 | } |
| 421 | + |
| 422 | + @FunctionalInterface |
| 423 | + private interface SessionFsOp<P, R> { |
| 424 | + |
| 425 | + CompletableFuture<R> call(SessionFsHandler handler, P params); |
| 426 | + } |
| 427 | + |
| 428 | + private <P, R> void handleSessionFsCall(JsonRpcClient rpc, String requestId, JsonNode params, String opName, |
| 429 | + Class<P> paramsClass, SessionFsOp<P, R> op) { |
| 430 | + runAsync(() -> { |
| 431 | + try { |
| 432 | + P p = MAPPER.treeToValue(params, paramsClass); |
| 433 | + String sessionId = params.has("sessionId") ? params.get("sessionId").asText() : null; |
| 434 | + CopilotSession session = sessionId != null ? sessions.get(sessionId) : null; |
| 435 | + if (session == null) { |
| 436 | + rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session: " + sessionId); |
| 437 | + return; |
| 438 | + } |
| 439 | + SessionFsHandler handler = session.getSessionFsHandler(); |
| 440 | + if (handler == null) { |
| 441 | + rpc.sendErrorResponse(Long.parseLong(requestId), -32603, |
| 442 | + "No sessionFs handler registered for session: " + sessionId); |
| 443 | + return; |
| 444 | + } |
| 445 | + op.call(handler, p).thenAccept(result -> { |
| 446 | + try { |
| 447 | + rpc.sendResponse(Long.parseLong(requestId), result); |
| 448 | + } catch (Exception e) { |
| 449 | + LOG.log(Level.SEVERE, "Error sending sessionFs." + opName + " response", e); |
| 450 | + } |
| 451 | + }).exceptionally(ex -> { |
| 452 | + try { |
| 453 | + rpc.sendErrorResponse(Long.parseLong(requestId), -32603, ex.getMessage()); |
| 454 | + } catch (IOException e) { |
| 455 | + LOG.log(Level.SEVERE, "Failed to send sessionFs." + opName + " error", e); |
| 456 | + } |
| 457 | + return null; |
| 458 | + }); |
| 459 | + } catch (Exception e) { |
| 460 | + LOG.log(Level.SEVERE, "Error handling sessionFs." + opName, e); |
| 461 | + try { |
| 462 | + rpc.sendErrorResponse(Long.parseLong(requestId), -32603, e.getMessage()); |
| 463 | + } catch (IOException ioe) { |
| 464 | + LOG.log(Level.SEVERE, "Failed to send error response", ioe); |
| 465 | + } |
| 466 | + } |
| 467 | + }); |
| 468 | + } |
| 469 | + |
| 470 | + private <P> void handleSessionFsVoidCall(JsonRpcClient rpc, String requestId, JsonNode params, String opName, |
| 471 | + Class<P> paramsClass, SessionFsOp<P, Void> op) { |
| 472 | + handleSessionFsCall(rpc, requestId, params, opName, paramsClass, (h, p) -> op.call(h, p).thenApply(v -> null)); |
| 473 | + } |
382 | 474 | } |
0 commit comments