Overview
When a user sends a message in the ADK Utils Example chat interface, it goes through a sophisticated flow involving the Next.js API route, the GenAIAgentService utility, the ADK agent, and potentially multiple tools before streaming back to the user. This page explains the complete request lifecycle with real code examples.Visual Flow Diagram
The following sequence diagram illustrates the complete request flow:Step-by-Step Flow
User sends message in browser
The user types a message and clicks send. The The
page.tsx component handles the submission.Code: app/page.tsx:45-48sendUserMessage function is rate-limited using @tanstack/react-pacer:useChat hook sends POST request
The The request includes all previous messages in the conversation history.
useChat hook from @ai-sdk/react sends a POST request to /api/genai-agent.Code: app/page.tsx:18-23API Route receives request
The The route imports the
/api/genai-agent endpoint receives the POST request with the messages array.Code: app/api/genai-agent/route.ts:5-16rootAgent from app/agents/agent1.ts and initializes the GenAIAgentService.GenAIAgentService processes request
The Key responsibilities:
GenAIAgentService from @yagolopez/adk-utils validates messages and creates a streaming response.Code: app/api/genai-agent/route.ts:18The
GenAIAgentService is a utility class from the @yagolopez/adk-utils package that simplifies integration between ADK agents and Next.js API routes.- Message validation
- Format conversion between AI SDK and ADK formats
- Streaming response management
- Error handling
ADK Agent processes the request
The The agent:
rootAgent (an LlmAgent instance) receives the processed messages.Code: app/agents/agent1.ts:62-75- Analyzes the user’s message
- Determines if it needs to use a tool
- Generates a response or tool call
Tool execution (if needed)
If the agent decides to use a tool, it executes the appropriate Available Tools:
FunctionTool.Example Tool: get_current_time (app/agents/agent1.ts:6-20)get_current_time- Retrieves time for any citycreate_mermaid_diagram- Generates Mermaid diagramsview_source_code- Shows source code examples
Response streams back to client
The agent’s response (including tool results) streams back through the service to the client.The response is a Server-Sent Events (SSE) stream that allows real-time token-by-token delivery.Client-side handling: app/page.tsx:79-91
UI renders the response
The The component uses Streamdown with plugins for:
ChatMessage component renders the streamed response with Markdown, code highlighting, and Mermaid diagrams.Code: components/chat-message.tsx:100-108- Syntax highlighting (via
@streamdown/code) - Mermaid diagram rendering (via
@streamdown/mermaid)
Key Components
1. GenAIAgentService (@yagolopez/adk-utils)
Purpose
The
GenAIAgentService bridges the gap between the AI SDK and ADK, providing a simplified API for agent communication.validateMessages(messages)- Validates the messages arraycreateStreamingResponse(messages)- Creates a streaming SSE responsecreateErrorResponse(message, status, error?)- Creates error responses
2. OllamaModel (@yagolopez/adk-utils)
Purpose
The
OllamaModel class enables ADK agents to use Ollama models (local or remote).- Local:
http://localhost:11434 - Remote:
https://ollama.com(for cloud models)
3. Rate Limiting
Implemented using@tanstack/react-pacer:
Configuration: lib/constants.ts:26-27
Data Format
Request Format
The API route receives an array ofUIMessage objects:
Response Format
The response is a streaming SSE response with incremental text chunks:The AI SDK automatically handles the streaming response and updates the
messages array in real-time.Error Handling
Errors are caught at multiple levels: 1. Route-level error handling: app/api/genai-agent/route.ts:19-26Streaming Mechanism
Service creates ReadableStream
The
GenAIAgentService creates a ReadableStream that emits chunks as they’re generated.AI SDK consumes stream
The
useChat hook subscribes to the stream and updates the messages state in real-time.Auto-scroll to bottom
Performance Considerations
Rate Limiting
20 messages per hour per user prevents API abuse
Streaming Responses
Progressive rendering improves perceived performance
Auto-scroll Optimization
Efficient scrolling prevents layout thrashing
Component Memoization
React optimizations reduce unnecessary re-renders
Related Pages
Project Structure
Explore the complete directory structure
Root Agent
Learn about Google ADK agents and tools
API Routes
API endpoint reference documentation
Chat Components
UI component documentation