Skip to content

Commit 9965f30

Browse files
authored
feat: hook up agent acp setup to electron (#181)
This does a lot of stuff: it fixes a bunch of mistakes I made in the previous PRs regarding how we handle ACP. notably: - the acp session id is now the task run id - for every action taken via ACP, we now write to S3 instead of manually appending (both client and agent) Note: this does _not_ yet support polling through cloud, we can do that in a separate PR. The UI is also very rough and will be refactored in another PR. We'll also then pass through the actual prompt we use in the task description, instead of requiring the user to input something. ![image.png](https://app.graphite.com/user-attachments/assets/b0e62d96-c919-40f3-b62a-4113a5436127.png)
1 parent 7717b56 commit 9965f30

39 files changed

+2804
-2457
lines changed

apps/array/src/api/generated.ts

Lines changed: 696 additions & 192 deletions
Large diffs are not rendered by default.

apps/array/src/main/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ import {
1212
} from "electron";
1313
import "./lib/logger";
1414
import { ANALYTICS_EVENTS } from "../types/analytics.js";
15-
import { registerAgentIpc, type TaskController } from "./services/agent.js";
15+
import {
16+
cleanupAgentSessions,
17+
registerAgentIpc,
18+
} from "./services/session-manager.js";
19+
20+
// Legacy type kept for backwards compatibility with taskControllers map
21+
type TaskController = unknown;
22+
1623
import { setupAgentHotReload } from "./services/dev-reload.js";
1724
import { registerFileWatcherIpc } from "./services/fileWatcher.js";
1825
import { registerFoldersIpc } from "./services/folders.js";
@@ -210,6 +217,14 @@ app.on("window-all-closed", async () => {
210217
}
211218
});
212219

220+
app.on("before-quit", async (event) => {
221+
event.preventDefault();
222+
await cleanupAgentSessions();
223+
trackAppEvent(ANALYTICS_EVENTS.APP_QUIT);
224+
await shutdownPostHog();
225+
app.exit(0);
226+
});
227+
213228
app.on("activate", () => {
214229
if (mainWindow === null) {
215230
createWindow();

apps/array/src/main/preload.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,37 @@ contextBridge.exposeInMainWorld("electronAPI", {
128128
ipcRenderer.invoke("clear-repo-file-cache", repoPath),
129129
agentStart: async (
130130
params: AgentStartParams,
131-
): Promise<{ taskId: string; channel: string }> =>
131+
): Promise<{ sessionId: string; channel: string }> =>
132132
ipcRenderer.invoke("agent-start", params),
133-
agentCancel: async (taskId: string): Promise<boolean> =>
134-
ipcRenderer.invoke("agent-cancel", taskId),
133+
agentPrompt: async (
134+
sessionId: string,
135+
text: string,
136+
): Promise<{ stopReason: string }> =>
137+
ipcRenderer.invoke("agent-prompt", sessionId, text),
138+
agentCancel: async (sessionId: string): Promise<boolean> =>
139+
ipcRenderer.invoke("agent-cancel", sessionId),
140+
agentListSessions: async (
141+
taskId?: string,
142+
): Promise<
143+
Array<{
144+
sessionId: string;
145+
acpSessionId: string;
146+
channel: string;
147+
taskId: string;
148+
}>
149+
> => ipcRenderer.invoke("agent-list-sessions", taskId),
150+
agentLoadSession: async (sessionId: string, cwd: string): Promise<boolean> =>
151+
ipcRenderer.invoke("agent-load-session", sessionId, cwd),
152+
agentReconnect: async (params: {
153+
taskId: string;
154+
taskRunId: string;
155+
repoPath: string;
156+
apiKey: string;
157+
apiHost: string;
158+
projectId: number;
159+
logUrl?: string;
160+
}): Promise<{ sessionId: string; channel: string } | null> =>
161+
ipcRenderer.invoke("agent-reconnect", params),
135162
onAgentEvent: (
136163
channel: string,
137164
listener: (payload: unknown) => void,

0 commit comments

Comments
 (0)