Skip to content

feat(ai-sessions): run the AI Architect chat on stored sessions - #22

Merged
Suharshit merged 1 commit into
mainfrom
feat/ai-sessions-wiring
Sep 15, 2026
Merged

Suharshit merged 1 commit into
mainfrom
feat/ai-sessions-wiring

Conversation

@Suharshit

Copy link
Copy Markdown
Owner

Stacked on #21. The base is feat/ai-sessions-storage, so this diff shows step 2 only. Merge #21 first, then change this PR's base to main.

Why

The AI sidebar lost its chat and any in-flight run on reload. This is step 2 of the AI sessions plan: the chat now reads and writes the sessions stored in #21. Generation is still one prompt → one design run; the clarify → plan → generate flow is step 3.

What

  • New turns route: POST /api/projects/[projectId]/ai-sessions/[sessionId]/turns with { type: "message", text }.
    • It checks access, then rejects with 409 if a reply is still pending or the chat would pass 60 messages.
    • It triggers design-agent and stores the prompt plus a PENDING reply carrying the run id. It also records the TaskRun row, moves the expiry forward and titles the chat from its first message.
    • If the trigger fails, it still stores the prompt with an error reply and returns 502.
  • Saving replies: GET .../ai-sessions/[sessionId] saves any finished runs before returning.
    • It reads each pending run with runs.retrieve. A success is saved as a RESULT with node and edge counts; a failure, cancellation or missing run becomes an ERROR.
    • A reply is therefore saved even if the tab closed mid-run, and the Trigger task still needs no database access.
    • When two reads settle the same reply at once, only one write happens and both return the saved reply.
  • Removed: POST /api/ai/design. The token route is unchanged.
  • Hook: useAiSession replaces useDesignAgent.
    • It reopens the chat last opened in this browser, or the most recent one.
    • A new chat is only stored when its first message is sent.
    • While a reply is pending it follows the run live through Trigger Realtime, and also re-reads the session every 4s in case the live connection drops.
  • Sidebar: a session bar with the current title, a saved-chats list (last activity, expiry, delete) and New chat, plus a loading state, a retryable load error, and scrolling to the latest message.
  • Refactors: the limit constants moved to lib/ai/session-limits.ts so the client can import them without Prisma. formatRelativeTime moved to lib/relative-time.ts.

Verification

  • pnpm typecheck and pnpm lint pass.
  • Database script:
    • a run that doesn't exist is saved as a failed reply
    • concurrent reads settle a reply once
    • a full chat or an unknown session is rejected
    • a pending reply blocks a new message (409)
    • a trigger failure returns 502 with the prompt stored before the error reply and no TaskRun row
  • Full run through a local trigger dev worker, on a throwaway project and Liveblocks room that were removed afterwards:
    • 202 with a PENDING reply and a TaskRun row
    • 409 for a second message while pending
    • the reply saved as "Added 3 components and 2 connections to the canvas."
    • re-reading the session changed nothing
  • Signed-out requests to the new routes are stopped by Clerk.
  • Not checked in a browser: the sidebar UI, resuming after a reload, switching and deleting chats, and the live progress line.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
draftly Ready Ready Preview Sep 15, 2026 6:42pm UTC

@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: b5368e3a-b424-450c-9816-6000f66afd83


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

A reload no longer loses the chat or an in-flight run. Generation is
still one-shot; this changes persistence and resume only.

- POST /api/projects/[projectId]/ai-sessions/[sessionId]/turns stores
  the prompt and a PENDING reply carrying the run id (replaces
  POST /api/ai/design, which is removed)
- Replies are settled from runs.retrieve whenever a session is read, so
  a turn is saved even if the tab closed mid-run; concurrent reads
  settle once
- useAiSession replaces useDesignAgent: reopens the last chat, resumes
  pending runs via Realtime with a 4s polling fallback, stores new chats
  lazily on the first message
- Sidebar session bar with saved-chat history (delete, expiry) and
  New chat
- Limits moved to lib/ai/session-limits.ts for client use;
  formatRelativeTime extracted to lib/relative-time.ts

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — ccbaf77f Deployed Sep 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant