Skip to content

Workflow Chat → production parity + retire rooms/memories #1785

Description

@sweetmantech

Tracking issue for bringing the new workflow chat to production parity and decommissioning the legacy substrate, following the /api/chat/workflow/api/chat cutover (chat#1767, shipped to prod 2026-06-05). The cutover is fully live; this issue captures the capabilities still stubbed/deferred and the legacy teardown. Inherited-gap detail lives in api#605.

Goal

/api/chat (durable Vercel Workflow + per-session sandbox) is the only chat path in prod. Make it feature-complete and production-grade: full streaming control, faithful tool-call UX, restored sandbox tools + artist context, correct telemetry/billing, docs in lockstep — then drop rooms/memories once no reader remains. Done = a user on chat.recoupable.com has everything they had pre-cutover, and the legacy tables are gone.

What shipped (context)

Done

  • docs#229 — align the Sessions OpenAPI spec with the live api.recoupable.com contract.
    ✅ Shipped 2026-06-05 (squash-merged to main, commit 2b683d5). Closes the former "Docs in lockstep" item.
    Renamed the PATCH request schema PatchSessionRequestPatchSessionBody (matches api's validatePatchSessionBody.ts); added artistId to Session.required typed OAS 3.1 ["string","null"] (was deprecated nullable: true); clarified isNewBranch as always-present on responses; hyperlinked the POST/GET/PATCH endpoints in the Session description and trimmed redundant schema descriptions (KISS, mirroring the CreateSessionRequest sibling).
    Verified: the "required" claims are accurate against api/lib/sessions/toSessionResponse.ts, which always emits isNewBranch and artistId — so the original "marked required but missing from responses" framing was a doc-clarity gap, not an API bug. An earlier patch.mdx frontmatter regression (dropped the OpenAPI file-path prefix → would break the PATCH page render) was caught in review and fixed in 05cd6a18. JSON valid; CI green (Mintlify/CodeRabbit/cubic); merged CLEAN.

Open — Streaming control & resilience

  • Stop actually halts the model. (server api#590 ✅ shipped; client chat#1770 pending)
    • Server — ✅ shipped 2026-06-06 (squash → test, then testmain via api#652; both synced). POST /api/chat/{chatId}/stop cancels the run, polls getRun().status every 150ms to trip an AbortController on the in-flight model loop, waits for terminal status (≤8s, else 504 with the slot held), then releases active_stream_id via CAS; runAgentWorkflow gates auto-commit on !result.aborted. Verified on preview: stop returned 200 {stopped:true} sub-second (~0.6–0.8s), the in-flight bash tool emitted tool-output-error: "Cancelled" (cancelled mid-execution), and active_stream_id cleared to null.
    • Remaining — client chat#1770: wire the Stop button to POST /api/chat/{chatId}/stop so the UI "clicking Stop" path is exercised end-to-end.
    • Done when: clicking Stop in the UI ends the stream within ~1s and wasAborted gates auto-commit.
  • Resume in-flight stream on reopen. (api#596 GET /api/chat/[chatId]/stream + chat#1771 + docs#225)

Open — Agent UX parity

  • Interactive tool-call traces. (chat#1780) — collapsible per-tool rendering incl. nested sub-agent calls; fixes broken multi-tool client traces.
  • Auto chat-title from first message. (net-new; api#605) — pairs with chat#1662 (new title not shown in sidebar). Done when: the first turn sets a generated (non-verbatim) title that shows in the sidebar.
  • Model picker polish. (chat#1682)
  • Edit / regenerate-from-message deletes from the wrong store (missed rooms/memories reader). (api#636 + chat#1776)
    • Why: DELETE /api/chats/{id}/messages/trailing still resolves and deletes via the legacy memories substrate (selectMemoriesfromTimestampdeleteMemories) — an untracked rooms/memories reader the cutover missed. Post-cutover history lives in chat_messages, so editing or regenerating from a prior turn in a workflow chat doesn't remove the trailing messages the user actually sees.
    • Fix: api#636 migrates validation + deletion to chat_messages — boundary {id, createdAt} deleted via the stable (created_at, id) ordering, mirroring open-agents' deleteChatMessageAndFollowing. chat#1776 threads transportChatId so the editor calls the endpoint with the session-scoped chat id. Confirm two open-agents parity behaviors are kept or consciously deferred: restrict deletion to role === "user", and bump last_assistant_message_at after delete.
    • Done when: editing/regenerating from a prior user message in a workflow chat removes that message + all newer from chat_messages (verified in DB), the sidebar's last message updates, and no memories reader remains on this path.

Open — Restore sandbox tools & context (net-new — biggest gap; "accepted regressions")

  • MCP tools in the workflow sandbox — artist data, music-industry APIs, send_email.
  • Composio tools — Sheets / Drive / Docs / TikTok.
  • Artist context in the system prompt.
  • Telegram new-conversation notifications.
    • Done when: a workflow chat can invoke these tools and the system prompt carries artist context, matching pre-cutover behavior.

Open — Telemetry & billing correctness (net-new; api#605)

  • Persist sandbox state after workflow finish — lifecycle timers stay stale otherwise.
  • Sub-agent (task tool) credit attribution — one usage_events row per sub-agent model (collectTaskToolUsageEvents).
  • workflow_runs telemetry.
  • Persist ask_user_question tool results across device switch.

Open — Phase 4 decommission (LAST — only after the workflow tools above are restored and stable)

  • Remove remaining rooms/memories readersgetGeneralAgent / setupChatRequest / setupToolsForRequest / MCP-Composio plumbing, still reachable via /api/chat/generate + Slack + email-inbound. (Note: the legacy handleChatStream/handleChatCompletion/app/api/chat/route.ts were already deleted in api#632; the current app/api/chat/route.ts is the canonical endpoint — do not delete it.)
  • Drop legacy rooms + memories tables — migration in recoupable/database (+ FK-dependents room_reports / segment_rooms / memory_emails). Destructive + irreversible — snapshot first; confirm zero readers.

Architecture decisions

  • Restore-before-remove. Workflow MCP/Composio (Restore-sandbox-tools bucket) must land before Phase 4 deletes the legacy tool plumbing, or capability is lost in the gap.
  • /api/chat is the single canonical chat path. /api/chat/generate + Slack + email-inbound are the remaining legacy rooms/memories readers Phase 4 targets.

Out of scope (separate trackers)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions