Skip to main content

Overview

The ADK Utils Example project follows Next.js 16 App Router conventions with a clear separation of concerns. The codebase is organized into logical directories that separate UI components, business logic, AI agents, and API routes.

Directory Structure

adk-utils-example/
├── app/                    # Next.js App Router (pages & API routes)
│   ├── agents/            # ADK agent definitions and tools
│   ├── api/               # API route handlers
│   │   ├── chat/         # Alternative chat endpoint
│   │   └── genai-agent/  # Main agent communication endpoint
│   ├── globals.css       # Global styles and Tailwind directives
│   ├── layout.tsx        # Root layout component
│   ├── page.tsx          # Home page (main chat interface)
│   └── favicon.ico       # Application icon
├── components/            # Reusable React UI components
│   ├── ui/               # shadcn/ui base components
│   ├── chat-empty-state.tsx
│   ├── chat-header.tsx
│   ├── chat-input.tsx
│   ├── chat-message.tsx
│   └── chat-typing-indicator.tsx
├── hooks/                 # Custom React hooks
│   ├── use-focus-on-load.ts
│   └── use-scroll-to-bottom.ts
├── lib/                   # Shared utilities and constants
│   ├── constants.ts      # App-wide constants (rate limits, suggestions)
│   └── utils.ts          # Utility functions
├── public/                # Static assets
│   ├── file.svg
│   ├── globe.svg
│   ├── next.svg
│   ├── vercel.svg
│   └── window.svg
├── e2e/                   # Playwright end-to-end tests
│   ├── chat.spec.ts
│   └── home.spec.ts
├── package.json           # Dependencies and scripts
├── tsconfig.json         # TypeScript configuration
└── tailwind.config.js    # Tailwind CSS configuration

Key Directories

/app

Next.js 16 App Router with pages, layouts, and API routes

/components

Reusable React UI components for the chat interface

/hooks

Custom React hooks for app functionality

/lib

Shared utilities, constants, and helper functions

/app Directory

The app directory contains all Next.js App Router pages and API routes.

/app/agents

This directory contains ADK agent definitions, tools, and configurations.
Key File: agent1.ts (lines 1-76)
import { FunctionTool, LlmAgent } from "@google/adk";
import { OllamaModel } from "@yagolopez/adk-utils";

export const rootAgent = new LlmAgent({
  name: "agent1",
  model: new OllamaModel("gpt-oss:120b-cloud", "https://ollama.com"),
  description: "Agent with three function tools...",
  instruction: `You are a helpful assistant...`,
  tools: [getCurrentTime, createMermaidDiagram, viewSourceCode],
});
Tools Defined:
  • get_current_time - Returns the current time in a specified city
  • create_mermaid_diagram - Creates Mermaid diagrams (flowchart, sequence, etc.)
  • view_source_code - Shows source code to the user
See app/agents/agent1.ts for the complete implementation.

/app/api

API routes that handle backend communication.

/app/api/genai-agent

This is the main endpoint for agent communication. It receives user messages and streams AI responses.
File: route.ts (lines 1-28)
import { rootAgent } from "@/app/agents/agent1";
import { GenAIAgentService } from "@yagolopez/adk-utils";

export async function POST(req: Request) {
  const { messages } = await req.json();
  const service = new GenAIAgentService(rootAgent);
  
  if (!service.validateMessages(messages)) {
    return GenAIAgentService.createErrorResponse("Messages are required", 400);
  }
  
  return service.createStreamingResponse(messages);
}
See app/api/genai-agent/route.ts for details.

/app/api/chat

Alternative chat endpoint (currently not used by the main UI).

Root App Files

FilePurposeLocation
page.tsxMain chat interface (home page)app/page.tsx
layout.tsxRoot layout with fonts and metadataapp/layout.tsx
globals.cssGlobal styles and Tailwind setupapp/globals.css

/components Directory

All UI components for the chat interface are located here.

chat-message.tsx

Renders individual chat messages with Markdown, code highlighting, and Mermaid diagrams

chat-input.tsx

Input field with submit, reset, and info buttons

chat-header.tsx

Header with title, suggestions, and reset functionality

chat-empty-state.tsx

Welcome screen shown when no messages exist

chat-typing-indicator.tsx

Animated indicator shown while AI is generating

ui/

shadcn/ui base components (Button, Tooltip, etc.)

ChatMessage Component

The ChatMessage component uses Streamdown with plugins for advanced rendering:
import { Streamdown } from "streamdown";
import { createCodePlugin } from "@streamdown/code";
import { createMermaidPlugin } from "@streamdown/mermaid";

const code = createCodePlugin({
  themes: ["vitesse-light", "vitesse-dark"],
});

const mermaid = createMermaidPlugin({ /* config */ });
See components/chat-message.tsx for the full implementation.

/hooks Directory

Custom React hooks that provide reusable functionality.

use-scroll-to-bottom.ts

Auto-scrolls chat container when new messages arrive

use-focus-on-load.ts

Automatically focuses input field on page load

/lib Directory

Shared utilities and constants used throughout the app.

constants.ts

Defines app-wide constants including:
  • Rate limiting: LIMIT = 20 messages per hour
  • Time window: ONE_HOUR_IN_MS = 60 * 60 * 1000
  • Suggestions: Array of pre-defined prompts with icons
See lib/constants.ts.

utils.ts

Utility functions for common operations like class name merging.

/e2e Directory

Playwright end-to-end tests for the application.

home.spec.ts

Tests for the home page rendering

chat.spec.ts

Tests for chat functionality and interactions
Run tests:
npm run test:e2e:headless  # Headless mode
npm run test:e2e:headed    # With browser UI
npm run test:e2e:ui        # Interactive UI mode

Configuration Files

package.json

Key Dependencies:
  • @google/adk - Google Agent Development Kit
  • @yagolopez/adk-utils - Enhanced Ollama model support
  • ai - Vercel AI SDK
  • next (16.1.6) - Next.js framework
  • react (19.2.4) - React library
  • streamdown - Markdown rendering with plugins
Key Scripts:
{
  "dev": "next dev",
  "build": "next build",
  "adk:web": "adk web ./app/agents/",
  "test": "jest",
  "test:e2e:headless": "playwright test --reporter=list"
}
See package.json for the complete configuration.

Next.js App Router Structure

1

File-based Routing

Pages are defined by files in the app/ directory. page.tsx becomes the route /.
2

Layouts

layout.tsx wraps all child pages and persists across navigation.
3

API Routes

API endpoints are created in app/api/ with route.ts files.
4

Server vs Client Components

By default, components are Server Components unless marked with "use client".
The main chat interface (app/page.tsx) is a Client Component because it uses React hooks like useState and useChat.

Request Flow

Learn how user messages flow through the system

Installation

Set up your development environment

Build docs developers (and LLMs) love