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