fix: relay Ask Proof comment to server ops endpoint so HTTP agents can poll it#38
fix: relay Ask Proof comment to server ops endpoint so HTTP agents can poll it#38luckydem wants to merge 1 commit intoEveryInc:mainfrom
Conversation
invokeAgentOnSelection only wrote a ProseMirror mark into the local Yjs document. While a live collab session is active the server blocks projection repair (recent_live_collab_lease), so HTTP-polling agents cannot see marks written this way. This change adds a fire-and-forget POST to /api/agent/:slug/ops immediately after the local mark is created. The server ops table is written directly to SQLite, bypassing the Yjs-to-projection pipeline entirely, so any polling agent sees the Ask Proof request the moment it is submitted. The local markComment call is preserved so the mark still appears inline in the editor for the user.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbe603703b
ℹ️ 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 body = JSON.stringify({ | ||
| type: 'comment.add', | ||
| by: actor, | ||
| quote: selectedText, | ||
| text: `@proof ${prompt}`, |
There was a problem hiding this comment.
Preserve a single comment identity across local and /ops writes
This payload creates a second independent comment instead of mirroring the local one: markComment(...) already creates a local mark ID, but /api/agent/:slug/ops → POST /marks/comment assigns a new randomUUID() when no ID is provided, and projection merge preserves DB-only mark IDs (mergePreservedActionMarks), so both comments survive and appear as duplicates after sync. Reuse the local mark ID (or avoid dual-writing the same comment) so one user action maps to one comment record.
Useful? React with 👍 / 👎.
| }).catch((err) => { | ||
| console.warn('[invokeAgentOnSelection] Failed to POST comment to server ops:', err); |
There was a problem hiding this comment.
Check /ops response success before treating request as queued
This call only catches thrown fetch errors and never inspects HTTP status, so non-2xx responses are silently ignored. comment.add can return a 409 anchor-not-found when the selected quote is newer than canonical markdown (a common live-collab state), so the backend request may fail while agent_manual_request_queued is still emitted, making Ask Proof look successful even though no pending event was created for polling agents.
Useful? React with 👍 / 👎.
Problem
invokeAgentOnSelectioncreates a ProseMirror mark viamarkCommentand writes it into the local Yjs document. While a live collab session is active, the server blocks projection repair withblockedReason: recent_live_collab_lease— so any HTTP-polling agent calling/state,/marks, or the bridge endpoints will see empty marks and never receive the request.The code comment already acknowledged this was incomplete:
But "Phase 1" was never wired up, leaving the Ask Proof UI with no backend path to an actual agent.
Fix
After creating the local mark, also fire a
POSTto/api/agent/:slug/opswithtype: comment.add. This writes directly to the server's ops table in SQLite, bypassing the Yjs-to-projection pipeline. Any HTTP-polling agent sees the Ask Proof request immediately, regardless of collab lease state.The local
markCommentcall is preserved so the inline mark still appears in the editor.Why this matters
Without this fix, the Ask Proof UI creates a strong expectation that an agent is listening — but nothing ever closes that loop. The feature is silently broken for any HTTP-based agent integration.
Testing
GET /api/agent/:slug/events/pendingwithin the same polling cycle