fix(#223): opt-in AGENTBRIDGE_ALWAYS_QUEUE mirrors Codex replies to fallback queue#234
Open
Seller-1990 wants to merge 2 commits into
Open
fix(#223): opt-in AGENTBRIDGE_ALWAYS_QUEUE mirrors Codex replies to fallback queue#234Seller-1990 wants to merge 2 commits into
Seller-1990 wants to merge 2 commits into
Conversation
…plies to fallback queue The Codex->Claude reply rides a fire-and-forget notifications/claude/channel notification. When the Claude session is idle the push is silently dropped upstream (Claude Code #61797), so pushViaChannel's catch never fires, the fallback queue is never populated, and get_messages stays empty -- the reply is unrecoverable (see raysonmeng#223). This adds an opt-in AGENTBRIDGE_ALWAYS_QUEUE=1 flag. When set, real Codex replies (non-"system_" ids) are also mirrored into the fallback queue after the channel push, so get_messages becomes a reliable pull path even for idle sessions. The channel push still fires (mid-turn liveness is unchanged), system messages are excluded to avoid flooding the queue, and a failed push still queues exactly once (no double-queue). Off by default -> delivery unchanged. - src/claude-adapter.ts: mirror-to-queue after push when flag is set - src/unit-test/message-delivery.test.ts: 4 tests - rebuilt committed bundles via bun run build:plugin Validation: bun run typecheck clean; bun run test:unit 1543 pass / 0 fail.
Contributor
|
Thanks for the PR! Before we can merge it, please sign our lightweight Contributor License Agreement — it keeps the project able to offer a future commercial edition alongside the open-source one. Reply here with: I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
…nmeng#223 shim Per Codex review feedback: - Note that system_ id prefix is used because BridgeMessage lacks a structural kind field; prefer such a field if added in the future. - Note that ALWAYS_QUEUE extends the fallback queue retention window (same data class, longer lifetime). - Rebuilt bundle.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (fixes #223)
Codex→Claude replies ride a fire-and-forget
notifications/claude/channelnotification. When the Claude session is idle, the push is silently dropped upstream (Claude Code #61797 — closed stale). Because nothing throws,pushViaChannel'scatchnever runs, the fallback queue is never populated, andget_messagesstayspending=0. The reply is unrecoverable: not rendered in-band, not pullable.Net effect: Claude→Codex works; Codex→Claude is lossy whenever Claude is idle.
require_reply: truedoes not help — the reply rides the same channel.I reproduced this on macOS (CC 2.1.205 + Codex 0.142.4): daemon logs
Pushed notification ✅whileget_messagesreturns empty on the same live adapter instance,dropped=0/pending=0— matching the three repros in #223.Fix
Opt-in
AGENTBRIDGE_ALWAYS_QUEUE=1. When set, after the channel push, real Codex replies (ids not prefixedsystem_) are also mirrored into the fallback queue, soget_messagesbecomes a reliable pull path even for idle sessions.system_*ids) are excluded so the queue isn't flooded with turn-start/turn-complete notifications.Why opt-in (not always-on)
Mirroring unconditionally would double-deliver when the channel push succeeds mid-turn (rendered once + drained once). Gating behind an env var keeps the default path byte-for-byte identical while giving idle-heavy setups a reliable fallback.
Changes
src/claude-adapter.ts: mirror-to-queue branch inpushViaChannel, gated on the flag + non-system id; header doc updated.src/unit-test/message-delivery.test.ts: 4 tests — mirror on real reply, exclude system ids, no double-queue on push failure, default stays push-only.plugins/agentbridge/server/{bridge-server,daemon}.js) viabun run build:pluginper CONTRIBUTING.Validation
bun run typecheck— cleanbun run test:unit— 1543 pass / 0 fail (4 new)Manual reproduction
With
AGENTBRIDGE_ALWAYS_QUEUE=1, send a Codex reply while the Claude session is idle: it now surfaces viaget_messagesinstead of being lost. Without the flag, behavior is unchanged.