Skip to content
Open
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
50 changes: 50 additions & 0 deletions template-nextjs-deepgram-voice-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ────────────────────────────────────────────────────────────────
# Required for core features (voice + AI + realtime DB)
# ────────────────────────────────────────────────────────────────

# Deepgram: Realtime speech-to-text
# Get your key at: https://console.deepgram.com/
DEEPGRAM_API_KEY=

# OpenRouter: LLM inference for agent logic & form generation
# Get your key at: https://openrouter.ai/keys
OPENROUTER_API_KEY=

# Convex: Realtime backend (auto-set by `npx convex dev` in most cases)
# If needed manually (e.g. production deploy), get from Convex dashboard
NEXT_PUBLIC_CONVEX_URL=


# ────────────────────────────────────────────────────────────────
# Optional: Authentication (Clerk) – comment out/remove if not using
# ────────────────────────────────────────────────────────────────

# Clerk: Modern auth provider
# Create app at: https://dashboard.clerk.com/
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=

# Optional redirect URLs after sign-in (customize as needed)
# Defaults work fine for most apps
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/home
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/home


# ────────────────────────────────────────────────────────────────
# Optional: Bot protection (Cloudflare Turnstile) – comment out/remove if not using
# ────────────────────────────────────────────────────────────────

# Cloudflare Turnstile: Invisible CAPTCHA alternative
# Get keys at: https://dash.cloudflare.com/ → Turnstile
NEXT_PUBLIC_TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=


# ────────────────────────────────────────────────────────────────
# Notes for users
# ────────────────────────────────────────────────────────────────
# - Do NOT commit real keys to git!
# - After copying to .env.local, restart your dev server if needed
# - Convex URL is usually injected automatically during `npx convex dev`
# - If you remove Clerk/Turnstile, update your code/components accordingly
# (e.g. remove auth wrappers, captcha checks)
42 changes: 42 additions & 0 deletions template-nextjs-deepgram-voice-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local


# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
21 changes: 21 additions & 0 deletions template-nextjs-deepgram-voice-agent/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Kollect

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
92 changes: 92 additions & 0 deletions template-nextjs-deepgram-voice-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Next.js + Convex + Deepgram Voice Agent

A starter template for building **realtime voice-based conversational agents** and dynamic forms/surveys.

- **Convex** — realtime database & serverless functions
- **Next.js** (App Router) — modern frontend
- **Deepgram** — realtime speech-to-text
- **Vercel AI SDK** + OpenRouter — agentic routing & structured outputs
- **Clerk** — optional authentication

Turn static forms into natural voice conversations: users speak answers, AI dynamically guides the flow, and everything syncs in realtime.

---

## Get Started

Create a new project with this template:

```bash
npm create convex@latest my-voice-agent -- -t nextjs-deepgram-voice-agent
```

(After merge, use the short name above. For now, test with your branch/fork using `-- -t YOUR-USERNAME/templates#add-template-nextjs-deepgram-voice-agent`)

Then:

1. Navigate to the project:
```bash
cd my-voice-agent
```

2. Install dependencies:
```bash
npm install
# or pnpm install / bun install
```

3. Copy and configure environment variables:
```bash
cp .env.local.example .env.local
```
Fill in your keys in `.env.local`:
- `DEEPGRAM_API_KEY=` (from Deepgram dashboard)
- `OPENROUTER_API_KEY=` (from OpenRouter)
- `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=` & `CLERK_SECRET_KEY=` (if using auth)
- Convex vars are auto-handled by `npx convex dev`

4. Start the Convex backend:
```bash
npx convex dev
```

5. Run the app:
```bash
npm run dev
```

Open http://localhost:3000 — grant microphone access, sign in (if auth enabled), describe/generate a form, or start a voice conversation.

---

## Features

- Realtime speech-to-text with Deepgram streaming
- AI-powered dynamic question routing & follow-ups
- Natural language form generation
- Realtime response storage & subscriptions via Convex
- Optional Clerk auth + Cloudflare Turnstile bot protection
- Tailwind CSS styling (minimal, no extra UI libraries)

---

## Customization

- Edit `convex/schema.ts` for your data model (e.g. sessions, questions, responses)
- Modify agent logic in `convex/` functions/actions (Vercel AI SDK tools/calls)
- Tweak voice UI in `app/page.tsx` or components
- Remove Clerk auth if not needed — it's optional

---

## Learn More

- [Convex Docs](https://docs.convex.dev)
- [Convex Auth Guide](https://docs.convex.dev/auth)
- [Deepgram Realtime API](https://developers.deepgram.com/docs)
- [Vercel AI SDK](https://sdk.vercel.ai/docs)
- [OpenRouter Docs](https://openrouter.ai/docs)

Join the [Convex Discord](https://discord.gg/convex) for help & community!

Built with ❤️ by [your-name-or-handle] — inspired by exploratory realtime AI projects.
90 changes: 90 additions & 0 deletions template-nextjs-deepgram-voice-agent/convex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Welcome to your Convex functions directory!

Write your Convex functions here.
See https://docs.convex.dev/functions for more.

A query function that takes two arguments looks like:

```ts
// convex/myFunctions.ts
import { query } from "./_generated/server";
import { v } from "convex/values";

export const myQueryFunction = query({
// Validators for arguments.
args: {
first: v.number(),
second: v.string(),
},

// Function implementation.
handler: async (ctx, args) => {
// Read the database as many times as you need here.
// See https://docs.convex.dev/database/reading-data.
const documents = await ctx.db.query("tablename").collect();

// Arguments passed from the client are properties of the args object.
console.log(args.first, args.second);

// Write arbitrary JavaScript here: filter, aggregate, build derived data,
// remove non-public properties, or create new objects.
return documents;
},
});
```

Using this query function in a React component looks like:

```ts
const data = useQuery(api.myFunctions.myQueryFunction, {
first: 10,
second: "hello",
});
```

A mutation function looks like:

```ts
// convex/myFunctions.ts
import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const myMutationFunction = mutation({
// Validators for arguments.
args: {
first: v.string(),
second: v.string(),
},

// Function implementation.
handler: async (ctx, args) => {
// Insert or modify documents in the database here.
// Mutations can also read from the database like queries.
// See https://docs.convex.dev/database/writing-data.
const message = { body: args.first, author: args.second };
const id = await ctx.db.insert("messages", message);

// Optionally, return a value from your mutation.
return await ctx.db.get("messages", id);
},
});
```

Using this mutation function in a React component looks like:

```ts
const mutation = useMutation(api.myFunctions.myMutationFunction);
function handleButtonPress() {
// fire and forget, the most common way to use mutations
mutation({ first: "Hello!", second: "me" });
// OR
// use the result once the mutation has completed
mutation({ first: "Hello!", second: "me" }).then((result) =>
console.log(result),
);
}
```

Use the Convex CLI to push your functions to a deployment. See everything
the Convex CLI can do by running `npx convex -h` in your project root
directory. To learn more, launch the docs with `npx convex docs`.
53 changes: 53 additions & 0 deletions template-nextjs-deepgram-voice-agent/convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable */
/**
* Generated `api` utility.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* To regenerate, run `npx convex dev`.
* @module
*/

import type * as form from "../form.js";
import type * as session from "../session.js";
import type * as survey from "../survey.js";

import type {
ApiFromModules,
FilterApi,
FunctionReference,
} from "convex/server";

declare const fullApi: ApiFromModules<{
form: typeof form;
session: typeof session;
survey: typeof survey;
}>;

/**
* A utility for referencing Convex functions in your app's public API.
*
* Usage:
* ```js
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
export declare const api: FilterApi<
typeof fullApi,
FunctionReference<any, "public">
>;

/**
* A utility for referencing Convex functions in your app's internal API.
*
* Usage:
* ```js
* const myFunctionReference = internal.myModule.myFunction;
* ```
*/
export declare const internal: FilterApi<
typeof fullApi,
FunctionReference<any, "internal">
>;

export declare const components: {};
23 changes: 23 additions & 0 deletions template-nextjs-deepgram-voice-agent/convex/_generated/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* eslint-disable */
/**
* Generated `api` utility.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* To regenerate, run `npx convex dev`.
* @module
*/

import { anyApi, componentsGeneric } from "convex/server";

/**
* A utility for referencing Convex functions in your app's API.
*
* Usage:
* ```js
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
export const api = anyApi;
export const internal = anyApi;
export const components = componentsGeneric();
Loading