Promote chat-workflow cutover stack to main
Promotes the chat-workflow cutover stack from test to main. This is the api half of the recoupable/chat#1747 bundle — pairs with recoupable/chat#TBD (the chat-side test→main PR).
What this ships
13 PRs since the original Phase 2 work began:
| PR | What |
|---|---|
| #562 | feat(api): migrate /api/sessions/[sessionId]/chats/[chatId] from open-agents |
| #578 | feat(sessions): enhance session patching with sandbox state management |
| #603 | feat(chat-workflow): persist assistant message per step |
| #614 | feat(chat-workflow): auto-commit + push after natural finish |
| #618 | feat(sessions): ensure personal repo on POST /api/sessions |
| #620 | feat(sessions): replace body cloneUrl+branch with organizationId |
| #623 | feat(backfill): Phase 2 rooms→sessions/chats/chat_messages script |
| #624 | feat: migrate POST /api/sessions/{sid}/chats/{cid}/read (workflow read receipts) |
| #626 | feat: migrate GET /api/chats to session-scoped shape (matches docs#227) |
| #627 | fix(backfill): store full UIMessage in chat_messages.parts |
| #628 | feat(sessions): accept artistId on POST /api/sessions |
| #629 | feat(backfill): include artist_id in session migration (straggler-aware) |
| #630 | feat(chats): exclude archived sessions from GET /api/chats |
23 commits ahead of main, 0 behind.
Wire-contract verification
All new/changed endpoints match their merged docs counterparts (recoupable/docs#227, docs#228) — verified live on preview deployments and on test-recoup-api.vercel.app.
GET /api/chatsreturns{id, title, accountId, sessionId, artistId, updatedAt}per row, no extras, no missing fields. Archived sessions excluded.POST /api/sessionsaccepts optionalartistId; persists onsessions.artist_id.GET /api/sessions/{sid}/chats/{cid}returns full message history fromchat_messages.
Data state in prod
- Phase 2 backfill: 23,252 rooms migrated, 46,212 well-formed memories → chat_messages.
- Straggler backfill ran via SQL today: 6 additional rooms migrated, 16 messages, all artist_ids carried through (api#629).
- 347 deleted-account rooms intentionally unmigrated.
sessions.artist_idpopulated for 17,991 of 17,991 rooms with an artist (100%).
Known accepted regressions
Per the chat#1747 issue body — these ship as-is and will be re-addressed post-promotion:
- No MCP tools (artist data, music industry APIs) inside the workflow sandbox
- No Composio tools (Sheets, Drive, Docs, TikTok)
- No artist context in system prompt
- No automatic chat title generation
- No
send_emailtool inside chat - No Telegram new-conversation notifications (re-scoped into a future credit-spend digest)
- Legacy
/api/chatendpoint still serves traffic from legacy/chat/[roomId]URLs (intentional dual-write torooms/memoriesduring the cutover; readers ofrooms/memoriesget cleaned up in Phase 4)
Ordering requirement
Merge api first. Wait for https://recoup-api.vercel.app to deploy. Then merge the chat test→main PR.
The chat side depends on endpoints that only exist in this PR:
- Canonical reader
GET /api/sessions/{sid}/chats/{cid}(#562) - Session-scoped chat update
PATCH /api/sessions/{sid}/chats/{cid} - Session archive
PATCH /api/sessions/{sid} { status: "archived" }(#578) - New
GET /api/chatsresponse shape +artist_account_idfilter (#626, #630) artistIdonPOST /api/sessions(#628)
If chat promotes first, every new chat 404s or hits the wrong shape on prod api.
Rollback plan
Revert the merge commit. No schema rollback needed — database#27 (sessions.artist_id column + inline backfill) is forward-compatible; legacy code paths still work with the column present-but-unused.
Test plan
- CI green on the merge commit
-
curl https://recoup-api.vercel.app/api/chats -H "x-api-key: ..."returns the session-scoped shape (noaccount_id,topic,updated_atlegacy fields; hasaccountId,sessionId,artistId,updatedAt) - Spot-check: archive a session via
PATCH /api/sessions/{sid} {"status":"archived"}and confirm its chats drop fromGET /api/chats - Then proceed to merge the chat test→main PR
Summary by cubic
Promotes the chat‑workflow cutover stack to main, delivering session‑scoped chats, read receipts, artist‑aware sessions, and the Phase 2 backfill. This is the API half of recoupable/chat#1747 — merge this first to unblock the chat test→main cutover.
-
New Features
- Session‑scoped chats:
GET /api/chatsjoins sessions and returns{ id, title, accountId, sessionId, artistId, updatedAt }; excludes archived sessions; supports artist filter; admin scope fixed for Bearer tokens. - Session chats:
GET/PATCH/DELETE /api/sessions/{sid}/chats/{cid}plusPOST /api/sessions/{sid}/chats/{cid}/readfor read receipts. - Sessions create:
POST /api/sessionsacceptsorganizationIdand optionalartistId, auto‑provisions the workspace repo, and returnsartistId. - Workflow reliability: persist assistant messages per step, auto‑commit + push on natural finish, and atomic credit deduction per turn.
- Backfill: idempotent rooms→sessions/chats/chat_messages script with pagination and batched writes.
- Session‑scoped chats:
-
Migration
- Merge order: merge API first, wait for
https://recoup-api.vercel.appto deploy, then merge the chat test→main PR. - Smoke checks:
GET /api/chatsreturns the new shape; archiving a session removes its chats from the list. - Rollback: revert the merge commit (schema is forward‑compatible).
- Merge order: merge API first, wait for