POST /api/chat/generate → 202 { runId } (async workflow run) — chat#1813#249
POST /api/chat/generate → 202 { runId } (async workflow run) — chat#1813#249sweetmantech wants to merge 6 commits into
Conversation
The scheduled chat-generation path is moving onto the durable runAgentWorkflow (recoupable/chat#1813). POST /api/chat/generate now starts a workflow run and returns { runId } with 202 instead of the synchronous completion body — message persistence + side effects (email) happen server-side after the response. - Replace the 200 ChatGenerateResponse with 202 ChatGenerateAcceptedResponse { runId }. - Drop the now-unused ChatGenerateResponse / ChatGenerateResponseMeta / ChatGenerateUsage / ContentPart schemas (each referenced only by the old 200). - Contract-first: this docs change leads the api re-point PR (docs → api). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe chat OpenAPI contract now defines asynchronous run creation and run status retrieval endpoints, returning ChangesAsync chat run OpenAPI contract
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api-reference/openapi/research.json`:
- Around line 669-674: The 202 accepted response for the chat generation
workflow only returns runId, which prevents callers from correlating or
retrieving a server-provisioned session when roomId is omitted. Update the
response contract in the ChatGenerateAcceptedResponse schema and the related
endpoint documentation/implementation to include the generated chat/session
identifiers (for example roomId and any persisted chat/session ID used by the
workflow) alongside runId, and ensure the accepted payload returned by the
run-start path matches this shape.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cc640d7c-0732-41da-85a8-6c91a7b98088
📒 Files selected for processing (1)
api-reference/openapi/research.json
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Add chatId + sessionId to ChatGenerateAcceptedResponse and document reading
the result via GET /api/chat/{chatId}/stream (or the chat's persisted
messages) — the workflow runId alone can't be resolved back to the output.
Matches the api#704 contract update. (chat#1813, review follow-up.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uns/{runId}
REST cleanup (chat#1813): the headless async endpoint creates a *run*, so it's
modeled as a run resource rather than a `generate` verb.
- Rename POST /api/chat/generate → POST /api/chat/runs (202 { runId, chatId,
sessionId } + Location header pointing at the run-status resource).
- Add GET /api/chat/runs/{runId} — point-in-time run status (ChatRunStatusResponse:
status/chatId/sessionId/timestamps/error). Documentation-driven: the api for
the status endpoint lands in a follow-up after this contract merges.
- Rename the reference page (generate.mdx → runs.mdx), add runs-status.mdx, update
docs.json nav + index.mdx.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| "/api/chat/generate": { | ||
| "post": { | ||
| "description": "Generate AI-powered text responses using the Recoup chat system. This endpoint processes chat requests and returns generated text along with metadata about the generation process.", | ||
| "description": "Start an asynchronous chat-generation run on the durable agent workflow (the same `runAgentWorkflow` that powers interactive `/api/chat`). The request provisions a session + sandbox and starts the run, then returns immediately with a `runId` (HTTP 202) — generation, message persistence, and any side effects (e.g. email) happen server-side after the response.", |
There was a problem hiding this comment.
Add bidirectional hyperlinks between
- /api/chat and /api/chat/runs with explicit note for when each should be used.
- /api/chat/runs and GET /api/chat/runs/{runId} with a note for how they relate
- /api/chat/runs and GET /api/chat/{chatId}/stream with a note for how they relate
KISS - Remove the request / response details in the description.
| "200": { | ||
| "description": "Chat generated successfully", | ||
| "202": { | ||
| "description": "Run accepted. A durable workflow run was started; `runId` identifies it. `chatId` / `sessionId` identify the persisted output — read the result via `GET /api/chat/{chatId}/stream` (resume the stream) or the chat's persisted messages. Assistant messages are persisted server-side as the run streams.", |
There was a problem hiding this comment.
Create a bidirectional hyperlink between this doc page and GET /api/chat/{chatId}/stream with note on how they relate.
| }, | ||
| "/api/chat/runs/{runId}": { | ||
| "get": { | ||
| "description": "Get the status of an asynchronous chat-generation run started via `POST /api/chat/runs`. Returns a point-in-time snapshot — not the generated content. Fetch the produced messages via `chatId` (`GET /api/chat/{chatId}/stream`, or the chat's persisted messages).", |
There was a problem hiding this comment.
Bidirectional hyperlinks to referenced pages.
| "name": "runId", | ||
| "in": "path", | ||
| "required": true, | ||
| "description": "The durable workflow run id returned by `POST /api/chat/runs`.", |
There was a problem hiding this comment.
Bidirectional hyperlinks
| "properties": { | ||
| "runId": { | ||
| "type": "string", | ||
| "description": "Durable workflow run id for the started generation. Same identifier surfaced as the `x-workflow-run-id` header on interactive `/api/chat`.", |
There was a problem hiding this comment.
Bidirectional hyperlinks with /api/chat
| "chatId": { | ||
| "type": "string", | ||
| "format": "uuid", | ||
| "description": "Chat the run writes its assistant messages to. Use with `GET /api/chat/{chatId}/stream` to resume the stream, or to fetch the persisted messages.", |
There was a problem hiding this comment.
Bidirectional hyperlinks for GET /api/chat/{chatId}/stream
There was a problem hiding this comment.
1 issue found across 6 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="index.mdx">
<violation number="1" location="index.mdx:176">
P2: Custom agent: **Documentation and Naming Conventions for Maintainable Code**
The `/api/chat/generate` endpoint still exists (re-pointed to async with 202 response) but was removed from the API overview list, making the documentation inaccurate. The list should include `generate` alongside any newly added endpoints.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| - **`/api/research/*`** — Artist research (search, lookup, profile, metrics, audience, cities, similar, urls, instagram-posts, playlists, albums, track, tracks, career, insights, genres, festivals, web, deep, people, extract, enrich, milestones, venues, rank, charts, radio, discover, curator, playlist) | ||
| - **`/api/content/*`** — Content creation (create, generate-image, generate-video, generate-caption, transcribe-audio, edit, upscale, analyze-video, templates, validate, estimate) | ||
| - **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, generate, stream, compact) | ||
| - **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, runs, runs-status, stream, compact) |
There was a problem hiding this comment.
P2: Custom agent: Documentation and Naming Conventions for Maintainable Code
The /api/chat/generate endpoint still exists (re-pointed to async with 202 response) but was removed from the API overview list, making the documentation inaccurate. The list should include generate alongside any newly added endpoints.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At index.mdx, line 176:
<comment>The `/api/chat/generate` endpoint still exists (re-pointed to async with 202 response) but was removed from the API overview list, making the documentation inaccurate. The list should include `generate` alongside any newly added endpoints.</comment>
<file context>
@@ -173,7 +173,7 @@ If you are an LLM navigating these docs, here is a summary of the endpoint struc
- **`/api/research/*`** — Artist research (search, lookup, profile, metrics, audience, cities, similar, urls, instagram-posts, playlists, albums, track, tracks, career, insights, genres, festivals, web, deep, people, extract, enrich, milestones, venues, rank, charts, radio, discover, curator, playlist)
- **`/api/content/*`** — Content creation (create, generate-image, generate-video, generate-caption, transcribe-audio, edit, upscale, analyze-video, templates, validate, estimate)
-- **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, generate, stream, compact)
+- **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, runs, runs-status, stream, compact)
- **`/api/songs/*`** — Songs and catalogs (songs, create, analyze, analyze-presets, catalogs, catalogs-create, catalogs-delete, catalog-songs, catalog-songs-add, catalog-songs-delete)
- **`/api/tasks/*`** — Task automation (get, create, update, delete, runs)
</file context>
| - **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, runs, runs-status, stream, compact) | |
| + - **`/api/chat/*`** — Chat (chats, artist, messages, messages-copy, messages-trailing-delete, create, update, delete, generate, runs, runs-status, stream, compact) |
…descriptions Per review on #249: each related chat endpoint now links to its siblings with a note on when to use which — - POST /api/chat ↔ POST /api/chat/runs (interactive-stream vs headless-job) - POST /api/chat/runs ↔ GET /api/chat/runs/{runId} (start vs status) - POST /api/chat/runs ↔ GET /api/chat/{chatId}/stream (start vs watch-live) - GET /api/chat/runs/{runId} ↔ GET /api/chat/{chatId}/stream (is-it-done vs watch-content) Descriptions trimmed to the essentials (request/response fields auto-render from the schema). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed your review in Bidirectional cross-links — every related chat endpoint now links its siblings, each with a "when to use which" note:
KISS — trimmed the run descriptions to essentials; request/response fields auto-render from the schema, so they're no longer restated in prose. The |
| "/api/chat/runs": { | ||
| "post": { | ||
| "description": "Generate AI-powered text responses using the Recoup chat system. This endpoint processes chat requests and returns generated text along with metadata about the generation process.", | ||
| "description": "Start an asynchronous, headless chat-generation run on the durable agent workflow — the same engine as interactive [POST /api/chat](/api-reference/chat/workflow). Provisions a session + sandbox and returns immediately (**202**) with `runId`, `chatId`, and `sessionId`; generation and side effects (e.g. email) finish server-side.\n\n**Related endpoints**\n- [POST /api/chat](/api-reference/chat/workflow) — use that for **interactive, streaming** turns on an existing chat; use this for **headless/programmatic** runs (no browser or pre-provisioned session needed).\n- [GET /api/chat/runs/{runId}](/api-reference/chat/runs-status) — poll to learn **whether** the run finished (and if it succeeded).\n- [GET /api/chat/{chatId}/stream](/api-reference/chat/workflow-stream) — **watch the output live** by passing the returned `chatId`.", |
There was a problem hiding this comment.
KISS
| "description": "Start an asynchronous, headless chat-generation run on the durable agent workflow — the same engine as interactive [POST /api/chat](/api-reference/chat/workflow). Provisions a session + sandbox and returns immediately (**202**) with `runId`, `chatId`, and `sessionId`; generation and side effects (e.g. email) finish server-side.\n\n**Related endpoints**\n- [POST /api/chat](/api-reference/chat/workflow) — use that for **interactive, streaming** turns on an existing chat; use this for **headless/programmatic** runs (no browser or pre-provisioned session needed).\n- [GET /api/chat/runs/{runId}](/api-reference/chat/runs-status) — poll to learn **whether** the run finished (and if it succeeded).\n- [GET /api/chat/{chatId}/stream](/api-reference/chat/workflow-stream) — **watch the output live** by passing the returned `chatId`.", | |
| "description": "Start an asynchronous, headless chat-generation run on the durable agent workflow — the same engine as interactive [POST /api/chat](/api-reference/chat/workflow).\n\n**Related endpoints**\n- [POST /api/chat](/api-reference/chat/workflow) — use that for **interactive, streaming** turns on an existing chat; use this for **headless/programmatic** runs (no browser or pre-provisioned session needed).\n- [GET /api/chat/runs/{runId}](/api-reference/chat/runs-status) — poll to learn **whether** the run finished (and if it succeeded).\n- [GET /api/chat/{chatId}/stream](/api-reference/chat/workflow-stream) — **watch the output live** by passing the returned `chatId`.", |
| "get": { | ||
| "summary": "Resume a chat response stream", | ||
| "description": "Reconnects to an in-progress chat response — the resume counterpart to [POST /api/chat](/api-reference/chat/workflow), which never resumes. Returns the live Server-Sent Events stream when a response is still being generated, or `204 No Content` when there is nothing to resume. The chat must belong to the authenticated account.", | ||
| "description": "Reconnects to an in-progress chat response — the resume counterpart to [POST /api/chat](/api-reference/chat/workflow), which never resumes. Returns the live Server-Sent Events stream when a response is still being generated, or `204 No Content` when there is nothing to resume. The chat must belong to the authenticated account.\n\n**Related endpoints**\n- [POST /api/chat/runs](/api-reference/chat/runs) — start a **headless** run, then pass the returned `chatId` here to **watch its output live**.\n- [GET /api/chat/runs/{runId}](/api-reference/chat/runs-status) — check **whether** that run finished (status, not content).", |
There was a problem hiding this comment.
Please add /api/chat as well.
| "post": { | ||
| "summary": "Stream sandbox-driven chat (Vercel Workflow)", | ||
| "description": "Streams an agent loop running as a durable [Vercel Workflow](https://vercel.com/docs/workflow) against the session's sandbox. The agent uses sandbox-only tools (`bash`, `read`, `write`, `grep`, `glob`, `todo`, `task`, `ask_user_question`, `skill`, `fetch`) — no MCP or Composio. Requires a sandbox provisioned via [POST /api/sandbox](/api-reference/sandbox/create).", | ||
| "description": "Streams an agent loop running as a durable [Vercel Workflow](https://vercel.com/docs/workflow) against the session's sandbox. The agent uses sandbox-only tools (`bash`, `read`, `write`, `grep`, `glob`, `todo`, `task`, `ask_user_question`, `skill`, `fetch`) — no MCP or Composio. Requires a sandbox provisioned via [POST /api/sandbox](/api-reference/sandbox/create).\n\n**Related endpoints**\n- [POST /api/chat/runs](/api-reference/chat/runs) — the **headless** counterpart: it provisions its own session + sandbox and runs without a streaming client. Use that for tasks/cron/programmatic runs; use this for **interactive, streaming** turns on an existing chat.\n- [GET /api/chat/{chatId}/stream](/api-reference/chat/workflow-stream) — reconnect to an in-progress response.", |
There was a problem hiding this comment.
Please add /api/chat as well.
…riptions Convert the remaining bare-`code` endpoint references into reference-page hyperlinks (review #249) so every cross-reference is clickable + bidirectional: - 202 response description → GET /api/chat/{chatId}/stream, GET /api/chat/runs/{runId} - runId path-parameter → POST /api/chat/runs - ChatGenerateAcceptedResponse.runId → POST /api/chat - ChatGenerateAcceptedResponse.chatId → GET /api/chat/{chatId}/stream Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cription Per review #249: - Every chat endpoint's "Related endpoints" list now links the other three siblings (POST /api/chat ↔ POST /api/chat/runs ↔ GET /api/chat/runs/{runId} ↔ GET /api/chat/{chatId}/stream) — full symmetry. - Applied the KISS suggestion: trimmed the POST /api/chat/runs description to the essential sentence + the Related list (provision/202/field details auto-render from the schema). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed the latest round in Full bidirectional symmetry — every chat endpoint's Related endpoints list now links the other three:
On the Hyperlinked the remaining bare- KISS — applied your suggestion: the |
PR 1 (docs, the contract) of the async chat-generation migration tracked in recoupable/chat#1813 — docs → api → tasks order.
What
POST /api/chat/generateis being re-pointed from a synchronous legacyToolLoopAgentonto the durablerunAgentWorkflow. It now starts a workflow run and returns{ runId }with HTTP 202 instead of the full completion body.200 ChatGenerateResponsewith202 ChatGenerateAcceptedResponse { runId }.ChatGenerateResponse/ChatGenerateResponseMeta/ChatGenerateUsage/ContentPartschemas (each was referenced only by the old 200 — verified, no dangling$refs).400unchanged.Why the contract can change
The only caller (
tasks/src/recoup/generateChat.ts) used the response only for logging; message persistence + email happen server-side. The api PR makes the caller fire-and-forget.Merge order
This docs PR lands first (contract), then api re-points to fulfill it, then tasks goes fire-and-forget.
🤖 Generated with Claude Code
Summary by cubic
Expose chat-generation as async runs. POST /api/chat/runs starts a durable workflow and returns 202 with runId, chatId, sessionId + Location; poll GET /api/chat/runs/{runId} and stream via GET /api/chat/{chatId}/stream (chat#1813).
Written for commit 651ec32. Summary will update on new commits.
Summary by CodeRabbit
POST /api/chat/runsnow returns immediately with HTTP202, along withrunId,chatId, andsessionId.GET /api/chat/runs/{runId}to retrieve the run’s current status.