Act as a senior frontend engineer.
I have an already initialized Next.js project. Your task is to build a chat based AI agent UI in this Next.js app that talks to the user and uses Composio Tool Router to interact with Google Calendar. The agent should be able to create, list, and delete meetings in the user's calendar based on natural language messages, and show clear, structured cards in the UI with the meeting details.
Composio Tool Router docs: https://docs.composio.dev/docs/tool-router/quick-start
Build everything from scratch inside this Next.js app.
- Use Next.js with the App Router and React.
- Use TypeScript for all React components and utility files.
- Use either CSS Modules or Tailwind CSS for styling. Pick one and stay consistent.
- All state should be managed on the client side. No separate backend code beyond what is needed to call the Composio Tool Router endpoint.
- Structure the project cleanly into components and feature folders so it is easy to understand and extend.
You can assume that there is a simple HTTP endpoint you can call on the server side that forwards tool calls to Composio Tool Router based on the model output. If you need to define basic API routes, do it within the same Next.js project.
Create a browser based chat application that behaves like a small personal assistant for Google Calendar:
-
Show a chat layout where:
- The user types messages in natural language.
- The assistant responds with text messages and calendar actions.
-
The agent should be able to:
- Create meetings in Google Calendar when asked.
- List upcoming events for today or a given date range when asked.
- Delete or cancel specific meetings when asked.
-
Whenever the agent performs a calendar action through Composio, it should:
- Use the tool responses to render a meeting card in the UI that shows key details.
-
The entire flow should feel conversational, with the agent:
- Confirming what it understood.
- Asking clarifying questions if information is missing.
- Explaining what it did after the tool call.
The focus is on the chat experience, clean tool integration through Composio Tool Router, and clear visual feedback after each action.
Build a dedicated chat UI page as the main interface.
-
Use a simple layout:
- A scrollable messages area.
- A message input area at the bottom.
-
Messages:
- User messages aligned to the right.
- Assistant messages aligned to the left.
- Each message should be rendered with a small avatar or label that indicates who sent it.
-
The assistant messages should be able to contain:
- Plain text.
- Optional meeting cards rendered under the message when a tool call succeeds.
-
Handle basic loading state:
- When the user sends a message and the assistant is calling the tool, show a small "typing" indicator or loading spinner in the assistant area.
State for the chat can be kept in a React state hook or a context provider.
The core of this app is the agent logic that decides when and how to use Composio Tool Router.
You do not need to implement the full LLM on the backend. Instead, design the frontend and TypeScript interfaces so that a model can:
- Read the conversation history.
- Decide which tool to call (if any).
- Send a request that hits a Next.js API route.
- Receive a structured tool response back.
You should clearly structure the agent side to cover these use cases:
The agent should handle at least the following kinds of natural language tasks:
-
Create a meeting Examples:
- "Create a meeting with john@example.com tomorrow at 3pm for 30 minutes"
- "Schedule a call with the design team next Monday at 10am CET"
- "Book a 1 hour session with Alice on Friday afternoon"
The agent should:
- Parse out date, time, duration, title, and attendees if present.
- Call the appropriate Composio tool through the Tool Router to create a Google Calendar event.
- After receiving the tool response, show a meeting card.
-
List events or agenda Examples:
- "What does my day look like?"
- "Show my meetings for tomorrow"
- "Do I have anything on my calendar next Wednesday?"
The agent should:
- Call Composio to fetch events from Google Calendar for the requested window.
- Render a list of meeting cards or a compact agenda view.
-
Delete or cancel a meeting Examples:
- "Cancel my 3pm meeting with John today"
- "Delete the standup tomorrow at 10am"
- "Cancel the last meeting you just created"
The agent should:
- Identify which event to operate on.
- Call the appropriate Composio tool to delete or cancel the event.
- Show a card that reflects the cancelled meeting, with a visible "Cancelled" status.
For all these intents, the agent should:
-
Restate what it understood before calling a tool, for example:
- "Got it. I will create a 30 minute meeting with john@example.com tomorrow at 3pm in your current time zone."
-
Ask for clarification instead of guessing if required details are missing or ambiguous, for example:
- "I see you want to book a meeting with Alice, but you did not specify the date. Which day should I use?"
-
After the tool call completes:
- Confirm the action with a clear natural language summary.
- Render a meeting card using the tool response.
You can assume that responses from the Composio Tool Router for calendar actions come back in this shape:
type ToolResponse = {
toolType?: string;
result?: {
successful?: boolean;
data?: {
response_data?: {
summary?: string;
htmlLink?: string;
start?: { dateTime?: string; timeZone?: string };
end?: { dateTime?: string; timeZone?: string };
attendees?: {
email?: string;
organizer?: boolean;
responseStatus?: string;
self?: boolean;
}[];
organizer?: { email?: string; self?: boolean };
};
};
error?: unknown;
};
};Use this to build a MeetingCard component.
The meeting card should show:
- Title: from
summary. - Time: formatted using
start.dateTime,start.timeZone,end.dateTime, andend.timeZone. - Organizer:
organizer.email. - Attendees:
Create a clear boundary where the frontend calls a Next.js API route for tool interactions. For example:
-
POST /api/agent:-
Takes the current chat history and the latest user message.
-
Calls the LLM and Composio Tool Router.
-
Returns:
- Assistant messages.
- Any
ToolResponsefrom calendar tools.
-
You do not need to implement actual calls to an LLM, but structure the code assuming that:
- The frontend sends messages to
/api/agent. /api/agentreturns a JSON payload that the frontend maps toChatMessageobjects.
Document this contract in TypeScript interfaces so it is easy to plug in a real model later.
-
Use a clean, minimal chat design:
- Rounded message bubbles.
- Subtle background color differences for user vs assistant.
- Simple typography.
-
The meeting cards should visually stand out from regular text bubbles:
- Use a border, subtle shadow, or background to differentiate.
- Keep them compact but readable.
-
Handle edge cases:
- If
result.successfulis false orerroris present, render a clear error message in the assistant chat bubble. - If the agent cannot understand a request, it should respond with a friendly clarification question.
- If
The experience should feel like a lightweight personal calendar assistant inside a chat.
Provide:
-
A short explanation of the architecture and how the chat, agent logic, and Composio integration fit together.
-
A description of any new folders or files you create, for example:
components/ChatMessage.tsxcomponents/MeetingCard.tsxapp/api/agent/route.tslib/types.tsfor shared TypeScript types
-
The complete code for:
- The main chat page component.
- The chat message list and input components.
- The meeting card component.
- Any utility functions used to parse
ToolResponseinto meeting card props. - The API route mock or real implementation.
-
Instructions on how to run the project:
- Required environment variables (if any).
- The main route to open in the browser to interact with the chat agent.
The final result should be a working chat based calendar agent UI in Next.js where a user can talk in natural language, the agent uses Composio Tool Router to operate on Google Calendar, and the UI clearly reflects each calendar action using well designed meeting cards.