-
Notifications
You must be signed in to change notification settings - Fork 56
[flight-booking-agent] Multi-turn chat and message injection #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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]>
Signed-off-by: Peter Wielander <[email protected]>
| () => | ||
| new WorkflowChatTransport({ | ||
| api: '/api/chat', | ||
| onChatSendMessage: (response) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| await writer.write({ type: 'finish' }); | ||
| await writer.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| }); | ||
|
|
||
| // Update messages with the agent's response | ||
| messages.push(...result.messages.slice(messages.length)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| { params }: { params: Promise<{ id: string }> } | ||
| ) { | ||
| const { id: runId } = await params; | ||
| const { message } = await req.json(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Peter Wielander <[email protected]>
Signed-off-by: Peter Wielander <[email protected]>
…g added to conversation history in multi-turn conversations Co-authored-by: VaguelySerious <[email protected]>
| const { message: followUp } = await hook; | ||
|
|
||
| // Check for session end signal | ||
| if (followUp === '/done') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like hookPayload.done === true would be cleaner than a magic string, no?
| // All user messages come from stream markers (data-workflow chunks). | ||
| // No deduplication needed - single source of truth. | ||
| const messages = useMemo(() => { | ||
| const result: UIMessage<TMetadata, UIDataTypes>[] = []; | ||
|
|
||
| for (const msg of rawMessages) { | ||
| // Skip user messages from useChat (we only use stream markers) | ||
| if (msg.role === 'user') { | ||
| continue; | ||
| } | ||
|
|
||
| if (msg.role === 'assistant') { | ||
| // Process parts in order, extracting user messages from markers | ||
| let currentAssistantParts: typeof msg.parts = []; | ||
| let partIndex = 0; | ||
|
|
||
| for (const part of msg.parts) { | ||
| if (isUserMessageMarker(part)) { | ||
| const data = part.data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, I'm confused, I thought Variant B didn't use the data markers? How come we can't write msg.role === 'user' chunks directly to the stream?
|
@TooTallNate Messed up slightly - I had a Variant B that I liked but apparently it didn't work as intended and Claude went back to Variant A, essentially. Since the Docs PR and this PR are aligned in functionality and seem to work well, can you re-review with the idea that we'll merge both, and I'll then follow-up with a smaller polish PR improving on this setup so inject user messages as UIMessageChunks, which requires some changes to DurableAgent ? |
This makes multi-turn session the default for the flight booking app.
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
localStorageuse 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 previouslyAlso see vercel/workflow#739
Screenshots