feat(service): a sent message answers the transaction that wrote its row

Merged
CH
4d ago
+123-24

Service half of the send-message area of the txid rollout, following Neon's optimistic-mutations guide (https://neon.com/docs/ai/skills/neon-realtime/references/mutations.md). Ported from the service part of #4188 (closed when Realtime was switched off); the host wait follows in its own PR on top of #4423.

What changed

  • Database (writer.ts): the message insert's own RETURNING also reads pg_current_xact_id()::text. writeAwaitingLine answers that txid when it wrote the row; a line already standing under its key answers none. No extra transaction or round trip.
  • Service (steer.ts, messages-procedures.ts): steerCodingAgentWritten answers the outcome beside the txid, and steerCodingAgent keeps its answer for its other callers (chat notify, tools, automations). POST /api/agents/{id}/messages answers { agent, txid? }.
  • Features: codingAgentMessageAnswerSchema (wire) and codingAgentMessageAnswerViewSchema (view); the contract and HostedCodingAgentClient.message use them. txid is an optional key, so released desktops ignore it.

Tests

  • coding-agent-store.test.ts: a written line answers a decimal txid; a repeat under the same key answers none.
  • coding-agents-app.test.ts: the send route answers a txid for a fresh send and none for a repeat; the other send tests read the new answer schema.

Ran: typecheck for database, features, service, host; vitest run on the three touched test files; biome; oxlint.

Made with Luke


Devin Review