Skip to content

Conversation

@VaguelySerious
Copy link
Member

@VaguelySerious VaguelySerious commented Jan 16, 2026

This makes multi-turn session the default for the flight booking app. This is an alternative to #25, using a different pattern for user message persistence.

The docs PR vercel/workflow#759 also publishes the page on how to do chat session modeling, which includes example code snippets from this PR.

Critically, this PR also removes all localStorage use for persistence, with the exception of the last run ID. The durable streams serve as the main durability and storage. To do this, we also specifically persist user messages inside the stream, which wasn't done previously

Also see vercel/workflow#739

Difference in variants

Variant A lets useChat natively handle optimistic rendering of user messages, and writes custom data chunks to the stream that the client interprets as user messages.

Variant B writes user messages to the actual stream as user messages, so that the stream is the source of truth and consists of 100% normally interpretable UIMessageChunk chunks.

I prefer variant B, as it's better for later processing with AI SDK, since the user messages are inside the stream as the SDK would expect them to be.

The downside with Variant B is that is requires slightly more optimistic rendering code.

Screenshots

image

Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
() =>
new WorkflowChatTransport({
api: '/api/chat',
onChatSendMessage: (response) => {
Copy link
Contributor

@vercel vercel bot Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useChat hook receives resume: false on first render even when a stored session ID exists in localStorage, causing it to start a fresh connection instead of resuming the existing session.

Fix on Vercel

Comment on lines 34 to 35
await writer.write({ type: 'finish' });
await writer.close();
Copy link
Contributor

@vercel vercel bot Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The writeStreamClose function acquires a WritableStream writer lock but fails to release it in a try-finally block, and is missing the writer.close() call, causing a resource leak if write() fails

Fix on Vercel

});

// Update messages with the agent's response
messages.push(...result.messages.slice(messages.length));
Copy link
Contributor

@vercel vercel bot Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent responses not properly added to messages on subsequent conversation turns due to incorrect array slicing logic

Fix on Vercel

// Show pending message immediately for instant feedback
setPendingMessage(text);

try {
Copy link
Contributor

@vercel vercel bot Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition in setPendingMessage state setter inside useMemo - FIXED

Fix on Vercel

{ params }: { params: Promise<{ id: string }> }
) {
const { id: runId } = await params;
const { message } = await req.json();
Copy link
Contributor

@vercel vercel bot Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POST /api/chat/[id] lacks input validation for message field and runId parameter, causing client errors to return 500 instead of 400, exposing internal error details

Fix on Vercel

Signed-off-by: Peter Wielander <[email protected]>
VaguelySerious and others added 2 commits January 16, 2026 21:51
Signed-off-by: Peter Wielander <[email protected]>
…g added to conversation history in multi-turn conversations

Co-authored-by: VaguelySerious <[email protected]>
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.

2 participants