feat: add outbound stateful code bridge - #66
Conversation
|
@codex review exact head |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7cf9350772
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9be996f4ae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| const assignment = await this.readAssignment(assignmentId); | ||
| if (assignment == null || assignment.workerId !== workerId) continue; | ||
| if (assignment.incarnationId !== incarnationId) continue; |
There was a problem hiding this comment.
Avoid consuming assignments for another incarnation
During a rolling restart, a superseded worker can still have an outstanding /lease request when the replacement registers. Because every incarnation consumes the same queue and LPOP is destructive, the old request can remove an assignment intended for the replacement and this continue permanently discards it, leaving dispatch blocked until its deadline despite a live worker. Fresh evidence beyond the earlier fencing comment is that the current head performs the incarnation mismatch check only after removing the item; use per-incarnation queues or atomically claim only matching assignments.
Useful? React with 👍 / 👎.
| await this.request<BridgeSettlementResponse>( | ||
| this.assignmentUrl(assignment, 'settle'), | ||
| settlement, | ||
| signal, | ||
| ); |
There was a problem hiding this comment.
Quarantine state after ambiguous settlement failures
If a stateful sandbox execution succeeds but this settlement request fails before reaching Code API, executeAndSettle throws and the worker proceeds to reconnect without retrying the settlement. The server eventually times out and releases the lock, yet the session-routed sandbox retains the execution's mutations, so the next request observes state from an execution reported as failed. Fresh evidence beyond the finalization fix is that the current head quarantines only finalizer failures; retry settlement through the assignment deadline or quarantine/reset the workspace when delivery remains ambiguous.
Useful? React with 👍 / 👎.
| return Math.max( | ||
| 1, | ||
| Math.min( | ||
| MAX_ASSIGNMENT_TTL_SECONDS, |
There was a problem hiding this comment.
Keep assignment TTL aligned with the configured timeout
When JOB_TIMEOUT is configured above ten minutes, this cap expires the assignment record and worker lock before deadlineAtMs. Cancellation polling then sees the missing assignment and aborts the sandbox, while expiration of the lock can also admit another dispatch before the original deadline; consequently supported long-running jobs cannot complete safely. Size the Redis TTL from the full configured deadline plus grace, or reject timeout values exceeding this cap.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| private sandboxEndpointFor(assignment: BridgeAssignment): string { | ||
| if (assignment.runtimeSessionId == null) return this.sandboxEndpoint; |
There was a problem hiding this comment.
Route stateless affinity assignments away from the template
When the documented stateful worker configuration uses a {runtimeSessionId} endpoint template with CODEAPI_RUNTIME_SESSION_MODE=affinity, any hintless request is intentionally dispatched without a runtime session. This branch then returns the unresolved template, so the worker posts to a literal /sessions/{runtimeSessionId}/... route and the affinity mode's stateless fallback fails. Provide a separate stateless endpoint, substitute an ephemeral assignment-specific route, or require strict mode for templated workers.
Useful? React with 👍 / 👎.
Summary
remote-bridgeCode API sandbox backend@librechat/codeprotocol and outbound worker CLISecurity model
The worker authenticates with a separate operator token and only makes outbound long-poll requests. Code API retains public auth, policy, manifest, deadline, and normalization responsibilities. Assignments are single-active, generation-fenced, deadline-bound, cancellable, and settled with a one-time lease token. The bridge is transport, not a replacement for the hardened microVM/NsJail and egress controls.
Verification
npm testinpackages/code(2 passed)npm pack --dry-runfor@librechat/codeCompanion LibreChat implementation: danny-avila/LibreChat#15352