Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions flight-booking-app/app/api/chat/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { chatMessageHook } from '@/workflows/chat/hooks/chat-message';

/**
* POST /api/chat/[id]
*
* Sends a follow-up message to an existing chat session.
* The [id] parameter is the workflow run ID returned when starting the session.
*/
export async function POST(
req: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id: runId } = await params;
const { message } = await req.json();

console.log(`Follow-up for workflow: ${runId} message: ${message}`);

try {
// Resume the hook using the run ID as the token
// This injects the message into the workflow
await chatMessageHook.resume(runId, { message });
return Response.json({ success: true });
} catch (error) {
console.error(`Error resuming hook: ${runId}`, error);
return Response.json(
{ error: 'Failed to send message', details: String(error) },
{ status: 500 }
);
}
}
22 changes: 16 additions & 6 deletions flight-booking-app/app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ import { createUIMessageStreamResponse, type UIMessage } from 'ai';
import { start } from 'workflow/api';
import { chat } from '@/workflows/chat';

// Uncomment to simulate a long running Vercel Function timing
// out due to a long running agent. The client-side will
// automatically reconnect to the stream.
//export const maxDuration = 8;
/**
* Uncomment the following line to simulate a long running
* Vercel Function timing out due to a long running agent.
* The client-side will automatically reconnect to the stream.
*/
// export const maxDuration = 8;

/**
* POST /api/chat
*
* Starts a new multi-turn chat session. The workflow will handle all subsequent
* turns via the message hook - the client should use the run ID returned in
* the `x-workflow-run-id` header to send follow-up messages.
*/
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();

Expand All @@ -16,8 +25,9 @@ export async function POST(req: Request) {
return createUIMessageStreamResponse({
stream: workflowStream,
headers: {
// The workflow run ID is stored into `localStorage` on the client side,
// which influences the `resume` flag in the `useChat` hook.
// The workflow run ID is used by the client to:
// 1. Send follow-up messages via POST /api/chat/[id]
// 2. Reconnect to the stream via GET /api/chat/[id]/stream
'x-workflow-run-id': run.runId,
},
});
Expand Down
Loading