Skip to content

Commit

Permalink
📦 NEW: Nextjs Example
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadawais committed Jul 25, 2024
1 parent d39f27a commit 7cb88f9
Show file tree
Hide file tree
Showing 25 changed files with 6,563 additions and 0 deletions.
3 changes: 3 additions & 0 deletions examples/nextjs/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions examples/nextjs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

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

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions examples/nextjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
18 changes: 18 additions & 0 deletions examples/nextjs/app/api/langbase/pipe/generate-text/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Pipe} from 'langbase';

export async function POST(req: Request) {
// 0. Take out user prompt.
const {prompt} = await req.json();

// 1. Initiate the Pipe.
const pipe = new Pipe({apiKey: process.env.LANGBASE_PIPE_LESS_WORDY!});

// 3. Generate the text by asking a question.
const result = await pipe.generateText({
// Add user question prompt here to generate completion.
messages: [{role: 'user', content: prompt}],
});

// 4. Done: You got the generated completion on result.completion.
return Response.json(result);
}
35 changes: 35 additions & 0 deletions examples/nextjs/app/api/langbase/pipe/stream-text/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Pipe} from 'langbase';
import {NextRequest} from 'next/server';

export const runtime = 'edge';

export async function POST(req: NextRequest) {
const {prompt} = await req.json();

// 1. Initiate the Pipe.
const pipe = new Pipe({
apiKey: process.env.LANGBASE_PIPE_LESS_WORDY_STREAM!,
});

// 2. Generate a stream by asking a question
const stream = await pipe.streamText({
messages: [{role: 'user', content: prompt}],
});

// 3. Create a ReadableStream from the Langbase stream
const readableStream = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
controller.enqueue(JSON.stringify(chunk) + '\n');
}
controller.close();
},
});

// 4. Return the stream
return new Response(readableStream, {
headers: {
'Content-Type': 'application/x-ndjson',
},
});
}
Binary file added examples/nextjs/app/favicon.ico
Binary file not shown.
69 changes: 69 additions & 0 deletions examples/nextjs/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
}

.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
33 changes: 33 additions & 0 deletions examples/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {cn} from 'mxcn';
import type {Metadata} from 'next';
import {Inter as FontSans} from 'next/font/google';
import './globals.css';

const fontSans = FontSans({
subsets: ['latin'],
variable: '--font-sans',
});

export const metadata: Metadata = {
title: '⌘ Langbase with a Next App',
description: 'Generated by create next app',
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={cn(
'min-h-screen bg-background font-sans antialiased',
fontSans.variable,
)}
>
{children}
</body>
</html>
);
}
21 changes: 21 additions & 0 deletions examples/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import StreamTextRouteHandler from '@/components/langbase/stream-text-route-handler';

export default function Home() {
return (
<div className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="flex flex-col items-center justify-between gap-10 max-w-lg w-full">
<div className="flex flex-col gap-1 w-full">
<h2 className="text-2xl font-bold tracking-tight">
⌘ Langbase AI Pipe
</h2>
<p className="text-muted-foreground">
An AI agent that responds to your prompts.
</p>
</div>
{/* <GenerateTextRouteHandler /> */}
<StreamTextRouteHandler />
{/* <GenerateTextServerAction /> */}
</div>
</div>
);
}
17 changes: 17 additions & 0 deletions examples/nextjs/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
17 changes: 17 additions & 0 deletions examples/nextjs/components/langbase/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use server';

import {Pipe} from 'langbase';

export async function getGeneratedText(prompt: string) {
// 1. Initiate the Pipe.
const pipe = new Pipe({apiKey: process.env.LANGBASE_PIPE_LESS_WORDY!});

// 3. Generate the text by asking a question.
const result = await pipe.generateText({
// Add user question prompt here to generate completion.
messages: [{role: 'user', content: prompt}],
});

// 4. Done: You got the generated completion on result.completion.
return result;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use client';

import {Button} from '@/components/ui/button';
import {Input} from '@/components/ui/input';
import {useState} from 'react';

export default function GenerateTextRouteHandler() {
const [prompt, setPrompt] = useState('');
const [completion, setCompletion] = useState('');
const [loading, setLoading] = useState(false);

const handleSubmit = async (e: any) => {
e.preventDefault();
if (!prompt.trim()) return;

setLoading(true);
try {
const response = await fetch('/api/langbase/pipe/generate-text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({prompt}),
});

if (!response.ok) {
throw new Error('Network response was not ok');
}

const data = await response.json();
setCompletion(data.completion);
} catch (error) {
console.error('Error:', error);
setCompletion('An error occurred while generating the completion.');
} finally {
setLoading(false);
}
};

return (
<>
<div className="flex flex-col gap-2 w-full">
<p className="text-lg font-semibold">
1. Generate Text{' '}
<a
className="text-indigo-500"
href="https://langbase.com/docs"
>
`generateText()`
</a>{' '}
with Route Handler
</p>
<p className="text-muted-foreground">
Ask a prompt to generate a text completion.
</p>
</div>
<form
onSubmit={handleSubmit}
className="flex flex-col w-full items-center gap-2"
>
<Input
type="text"
placeholder="Enter prompt message here"
value={prompt}
onChange={e => setPrompt(e.target.value)}
required
/>

<Button type="submit" className="w-full" disabled={loading}>
{loading ? 'AI is thinking...' : 'Ask AI'}
</Button>
</form>

{!loading && completion && (
<p className="mt-4">
<strong>Completion:</strong> {completion}
</p>
)}
</>
);
}
Loading

0 comments on commit 7cb88f9

Please sign in to comment.