[WIP] effect-codex-app-server#1942
Conversation
- Generate schema and protocol typings from upstream codex app-server - Add tests and probe fixtures for protocol/client coverage - Co-authored-by: codex <codex@users.noreply.github.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
effect-codex-app-server
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Error recovery yields failure instead of fallback value
- Piped the Effect.tryPromise through Effect.orElseSucceed(() => "") so that a rejected response.text() recovers to an empty string success value instead of short-circuiting the generator with a bare empty string failure.
Or push these changes by commenting:
@cursor push cf803e8469
Preview (cf803e8469)
diff --git a/packages/effect-codex-app-server/scripts/generate.ts b/packages/effect-codex-app-server/scripts/generate.ts
--- a/packages/effect-codex-app-server/scripts/generate.ts
+++ b/packages/effect-codex-app-server/scripts/generate.ts
@@ -160,8 +160,9 @@
if (!response.ok) {
const detail = yield* Effect.tryPromise({
try: () => response.text(),
- catch: () => "",
- });
+ catch: (cause) =>
+ new GeneratorError({ detail: `Failed to read response body from ${url}`, cause }),
+ }).pipe(Effect.orElseSucceed(() => ""));
return yield* Effect.fail(
new GeneratorError({
detail: `Failed to download ${url}: ${response.status} ${detail}`,You can send follow-ups to the cloud agent here.
- Switch discovery probing to the typed Codex client - Add coverage for initialize, account, and skills parsing - Preserve account snapshot mapping for typed responses
- Split Codex app-server session logic into dedicated runtime modules - Update provider and adapter paths to use the new codex session flow - Refresh tests and developer instructions around Codex behavior
| Effect.gen(function* () { | ||
| const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; | ||
| const runtimeScope = yield* Scope.make("sequential"); | ||
| const events = yield* Queue.unbounded<ProviderEvent>(); |
There was a problem hiding this comment.
🟡 Medium codex/CodexSessionRuntime.ts:615
If makeCodexSessionRuntime fails after spawning the child process but before returning (e.g., Layer.build at line 644 throws), runtimeScope is never closed and the child process leaks because it was spawned with Effect.provideService(Scope.Scope, runtimeScope). The scope at line 617 has no automatic finalization handler, so any early exit bypasses cleanup.
Effect.gen(function* () {
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
- const runtimeScope = yield* Scope.make("sequential");
+ const runtimeScope = yield* Scope.make("sequential");
+ yield* Effect.addFinalizer(() => Scope.close(runtimeScope, Exit.void));
const events = yield* Queue.unbounded<ProviderEvent>();🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/server/src/provider/codex/CodexSessionRuntime.ts around lines 615-618:
If `makeCodexSessionRuntime` fails after spawning the child process but before returning (e.g., `Layer.build` at line 644 throws), `runtimeScope` is never closed and the child process leaks because it was spawned with `Effect.provideService(Scope.Scope, runtimeScope)`. The scope at line 617 has no automatic finalization handler, so any early exit bypasses cleanup.
Evidence trail:
Line 617 shows runtimeScope creation
- Add `packages/effect-codex-app-server/package.json` to the tracked workspace files - Keep release smoke coverage aligned with the repo package set
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue. You can view the agent here.
Reviewed by Cursor Bugbot for commit 3d9f655. Configure here.
| } | ||
|
|
||
| function normalizeItemType(raw: unknown): string { | ||
| const type = asString(raw); |
There was a problem hiding this comment.
Dropped "cancelled" case maps cancelled turns to "completed"
Medium Severity
The toTurnStatus function's return type includes "cancelled" but the switch statement no longer has a case "cancelled" branch — it was removed in this diff. If the Codex server sends a turn with "cancelled" status, it falls through to default and is incorrectly reported as "completed". The old code explicitly handled "cancelled" as a passthrough case.
Reviewed by Cursor Bugbot for commit 3d9f655. Configure here.
There was a problem hiding this comment.
Bugbot Autofix determined this is a false positive.
The upstream Codex schema (V2TurnCompletedNotification__TurnStatus) only defines "completed" | "interrupted" | "failed" | "inProgress" — "cancelled" is not a valid value and adding it causes a TypeScript compile error, so the server can never send it.
You can send follow-ups to the cloud agent here.



Typesafe JSONRPC effect API for Codex App Server. Generated from the protocol's JSON schemas
Note
Medium Risk
Moderate risk because it replaces the Codex provider transport/event plumbing and error mapping with a new runtime layer; regressions could affect session lifecycle, event streaming, and approval/user-input flows.
Overview
Migrates the server’s Codex integration from the in-repo
CodexAppServerManagerto the neweffect-codex-app-servertyped JSON-RPC runtime, managing oneCodexSessionRuntimeper thread and wiring itseventsstream into the existing canonical runtime event stream.Updates
CodexAdapterto create/stop runtimes onstartSession, routesendTurn/interruptTurn/readThread/rollbackThread/approval + user-input responses through the runtime, and map runtime errors into adapter errors (notablySessionNotFoundvs process/transport failures).Refactors Codex event mapping to decode payloads via generated schemas and adjusts a few mappings (e.g., stdout/stderr classification via runtime, output deltas emitted as
content.delta, user-input questionmultiSelectforced tofalse), updates tests to use a fake runtime + queue-backed event stream, and switches model capability import toprovider/codexModels.ts. Also adds theeffect-codex-app-serverdev dependency and removes the legacy manager implementation + its tests.Reviewed by Cursor Bugbot for commit 3d9f655. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add
effect-codex-app-serverpackage and refactor Codex adapter to use typed session runtimeseffect-codex-app-serverworkspace package with a typed JSON-RPC client, bidirectional stdio protocol, generated schemas from the OpenAI Codex protocol, and structured error types for spawn, transport, parse, and request failures.CodexAdapter.tsto manage per-threadCodexSessionRuntimeinstances instead of a singleCodexAppServerManager; each session now streams typed events directly from its own runtime fiber.codexAppServer.tswith an Effect-based client using the new package; skills and account data are now parsed via generated schemas.enrichCodexSnapshotViaDiscoveryinCodexProvider.ts, which merges discovered account auth and skills into the published provider snapshot.codexAppServerManager.tsand moves model constants to a dedicatedcodexModels.tsmodule.content.deltainstead oftool.progress;turn.completedno longer includes usage/cost fields);multiSelecton user-input questions is hardcoded tofalse.Macroscope summarized 3d9f655.