diff --git a/apps/server/src/provider/Layers/ProviderService.test.ts b/apps/server/src/provider/Layers/ProviderService.test.ts index d6976479af046e4ec32095239011c59b0bc58b53..b18a838939d31e2a6258f0c70798b2d64a80ba18 100644 --- a/apps/server/src/provider/Layers/ProviderService.test.ts +++ b/apps/server/src/provider/Layers/ProviderService.test.ts @@ -378,6 +378,7 @@ it.effect( [ { provider: "codex", + cwd: "/tmp/project", resumeThreadId: startedSession.threadId, }, ], @@ -465,6 +466,7 @@ routing.layer("ProviderServiceLive routing", (it) => { [ { provider: "codex", + cwd: "/tmp/project", resumeThreadId: initial.threadId, }, ], @@ -475,6 +477,38 @@ routing.layer("ProviderServiceLive routing", (it) => { }), ); + it.effect("recovers stale sessions for sendTurn using persisted cwd", () => + Effect.gen(function* () { + const provider = yield* ProviderService; + + const initial = yield* provider.startSession(asThreadId("thread-1"), { + provider: "codex", + cwd: "/tmp/project-send-turn", + }); + + yield* provider.stopAll(); + routing.codex.startSession.mockClear(); + routing.codex.sendTurn.mockClear(); + + yield* provider.sendTurn({ + sessionId: initial.sessionId, + input: "resume", + attachments: [], + }); + + assert.deepEqual(routing.codex.startSession.mock.calls, [ + [ + { + provider: "codex", + cwd: "/tmp/project-send-turn", + resumeThreadId: initial.threadId, + }, + ], + ]); + assert.equal(routing.codex.sendTurn.mock.calls.length, 1); + }), + ); + it.effect("stops all sessions and clears adapter runtime", () => Effect.gen(function* () { const provider = yield* ProviderService; diff --git a/apps/server/src/provider/Layers/ProviderService.ts b/apps/server/src/provider/Layers/ProviderService.ts index 1a50a95d22cc7d2164b2d91b21d611eab719c0b1..d49dc5579ffe887c479f45c3e0ab0f63a7f5eb42 100644 --- a/apps/server/src/provider/Layers/ProviderService.ts +++ b/apps/server/src/provider/Layers/ProviderService.ts @@ -93,6 +93,18 @@ function toRuntimePayloadFromSession(session: ProviderSession): Record 0 ? trimmed : undefined; +} + const makeProviderService = (options?: ProviderServiceLiveOptions) => Effect.gen(function* () { const canonicalEventLogger = @@ -266,8 +278,11 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => ); } + const persistedCwd = readPersistedCwd(input.binding.runtimePayload); + const resumed = yield* adapter.startSession({ provider: input.binding.provider, + ...(persistedCwd ? { cwd: persistedCwd } : {}), ...(resumeThreadId ? { resumeThreadId } : {}), ...(hasResumeCursor ? { resumeCursor: input.binding.resumeCursor } : {}), });