-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
📦 NEW: English (CEFR) level assessment bot (#4)
* gitignore * opening for cefr ai bot * header for cefr ai bot * nextjs chatui * udpate readme for cefr level assessment bot * update layout to include meta for cefr level assessment bot * spelling corrected * udpate package name for cefr level assessment bot
- Loading branch information
Showing
32 changed files
with
1,829 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# 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 | ||
.env*.local | ||
.copy.local.env | ||
.copy.remote.env | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
# Supabase | ||
seed.sql | ||
xseed.sql | ||
xxseed.sql | ||
-seed.sql | ||
/supabase/seed.sql | ||
/test-results/ | ||
/playwright-report/ | ||
/blob-report/ | ||
/playwright/.cache/ | ||
|
||
# No lock files. | ||
package-lock.json | ||
yarn.lock | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
![License: MIT][mit] [![Fork to ⌘ Langbase][fork]][pipe] | ||
|
||
## Build English (CEFR) Level Assessment Bot with Pipes — ⌘ Langbase | ||
|
||
This chatbot is built by using an AI Pipe on Langbase, it works with 30+ LLMs (OpenAI, Gemini, Mistral, Llama, Gemma, etc), any Data (10M+ context with Memory sets), and any Framework (standard web API you can use with any software). | ||
|
||
Check out the live demo [here][demo]. | ||
|
||
## Features | ||
|
||
- 💬 [CEFR Level Assessment Bot][demo] — Built with an [AI Pipe on ⌘ Langbase][pipe] | ||
- ⚡️ Streaming — Real-time chat experience with streamed responses | ||
- 🗣️ Q/A — Ask questions and get pre-defined answers with your preferred AI model and tone | ||
- 🔋 Responsive and open source — Works on all devices and platforms | ||
|
||
## Learn more | ||
|
||
1. Check the [CEFR Level Assessment Bot on ⌘ Langbase][pipe] | ||
2. Read the [source code on GitHub][gh] for this example | ||
3. Go through Documentaion: [Pipe Quick Start][qs] | ||
4. Learn more about [Pipes & Memory features on ⌘ Langbase][docs] | ||
|
||
## Get started | ||
|
||
Let's get started with the project: | ||
|
||
To get started with Langbase, you'll need to [create a free personal account on Langbase.com][signup] and verify your email address. _Done? Cool, cool!_ | ||
|
||
1. Fork the [CEFR Level Assessment Bot][pipe] Pipe on ⌘ Langbase. | ||
2. Go to the API tab to copy the Pipe's API key (to be used on server-side only). | ||
3. Download the example project folder from [here][download] or clone the reppository. | ||
4. `cd` into the project directory and open it in your code editor. | ||
5. Duplicate the `.env.example` file in this project and rename it to `.env.local`. | ||
6. Add the following environment variables (.env.local): | ||
``` | ||
# Replace `PIPE_API_KEY` with the copied API key. | ||
NEXT_LB_PIPE_API_KEY="PIPE_API_KEY" | ||
``` | ||
7. In your CLI issue the following: | ||
```sh | ||
# Install the dependencies using the following command: | ||
npm install | ||
|
||
# Run the project using the following command: | ||
npm run dev | ||
``` | ||
|
||
8. Your app template should now be running on [localhost:3000][local]. | ||
|
||
> NOTE: | ||
> This is a Next.js project, so you can build and deploy it to any platform of your choice, like Vercel, Netlify, Cloudflare, etc. | ||
--- | ||
|
||
## Authors | ||
|
||
This project is created by [Langbase][lb] team members, with contributions from: | ||
|
||
- Muhammad-Ali Danish - Software Engineer, [Langbase][lb] | ||
|
||
**_Built by ⌘ [Langbase.com][lb] — Ship hyper-personalized AI assistants with memory!_** | ||
|
||
|
||
[demo]: https://cefr-level-assessment-bot.langbase.dev | ||
[lb]: https://langbase.com | ||
[pipe]: https://beta.langbase.com/examples/cefr-level-assessment-bot | ||
[gh]: https://github.com/LangbaseInc/langbase-examples/tree/main/examples/cefr-level-assessment-bot | ||
[download]:https://download-directory.github.io/?url=https://github.com/LangbaseInc/langbase-examples/tree/main/examples/cefr-level-assessment-bot | ||
[signup]: https://langbase.fyi/io | ||
[qs]:https://langbase.com/docs/pipe/quickstart | ||
[docs]:https://langbase.com/docs | ||
[xaa]:https://x.com/MrAhmadAwais | ||
[xab]:https://x.com/AhmadBilalDev | ||
[local]:http://localhost:3000 | ||
[mit]: https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge&color=%23000000 | ||
[fork]: https://img.shields.io/badge/FORK%20ON-%E2%8C%98%20Langbase-000000.svg?style=for-the-badge&logo=%E2%8C%98%20Langbase&logoColor=000000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { OpenAIStream, StreamingTextResponse } from 'ai' | ||
|
||
export const runtime = 'edge' | ||
|
||
/** | ||
* Stream AI Chat Messages from Langbase | ||
* | ||
* @param req | ||
* @returns | ||
*/ | ||
export async function POST(req: Request) { | ||
try { | ||
if (!process.env.NEXT_LB_PIPE_API_KEY) { | ||
throw new Error( | ||
'Please set NEXT_LB_PIPE_API_KEY in your environment variables.' | ||
) | ||
} | ||
|
||
const endpointUrl = 'https://api.langbase.com/beta/chat' | ||
|
||
const headers = { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${process.env.NEXT_LB_PIPE_API_KEY}` | ||
} | ||
|
||
// Get chat prompt messages and threadId from the client. | ||
const body = await req.json() | ||
const { messages, threadId } = body | ||
|
||
const requestBody = { | ||
messages, | ||
...(threadId && { threadId }) // Only include threadId if it exists | ||
} | ||
|
||
// Send the request to Langbase API. | ||
const response = await fetch(endpointUrl, { | ||
method: 'POST', | ||
headers, | ||
body: JSON.stringify(requestBody) | ||
}) | ||
|
||
if (!response.ok) { | ||
const res = await response.json() | ||
throw new Error(`Error ${res.error.status}: ${res.error.message}`) | ||
} | ||
|
||
// Handle Langbase response, which is a stream in OpenAI format. | ||
const stream = OpenAIStream(response) | ||
// Respond with a text stream. | ||
return new StreamingTextResponse(stream, { | ||
headers: response.headers | ||
}) | ||
} catch (error: any) { | ||
console.error('Uncaught API Error:', error) | ||
return new Response(JSON.stringify(error), { status: 500 }) | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
/* Zinc */ | ||
/* --background: 240 10% 3.9%; */ | ||
/* --muted: 240 3.7% 15.9%; */ | ||
@layer base { | ||
:root { | ||
--background: 0 0% 100%; | ||
--foreground: 240 10% 3.9%; | ||
--card: 0 0% 100%; | ||
--card-foreground: 240 10% 3.9%; | ||
--popover: 0 0% 100%; | ||
--popover-foreground: 240 10% 3.9%; | ||
--primary: 240 5.9% 10%; | ||
--primary-foreground: 0 0% 98%; | ||
--secondary: 240 4.8% 95.9%; | ||
--secondary-foreground: 240 5.9% 10%; | ||
--muted: 240 4.8% 95.9%; | ||
--muted-foreground: 240 3.8% 46.1%; | ||
--accent: 240 4.8% 95.9%; | ||
--accent-foreground: 240 5.9% 10%; | ||
/* --destructive: 0 84.2% 60.2%; */ | ||
--destructive: 2.74 92.59% 62.94%; | ||
--destructive-foreground: 0 0% 98%; | ||
--warning: 46.38 70.61% 48.04%; | ||
--warning-foreground: 120 12.5% 3.14%; | ||
--border: 240 5.9% 90%; | ||
--input: 240 5.9% 90%; | ||
--ring: 240 5.9% 10%; | ||
--radius: 6px; | ||
--danger: 2.74 92.59% 62.94%; | ||
} | ||
|
||
.dark { | ||
/* --background: 120 12.5% 3.14%; */ | ||
--background: 240, 3%, 9%; | ||
--foreground: 0 0% 98%; | ||
--card: 240 10% 3.9%; | ||
--card-foreground: 0 0% 98%; | ||
--popover: 240 10% 3.9%; | ||
--popover-foreground: 0 0% 98%; | ||
--primary: 0 0% 98%; | ||
--primary-foreground: 240 5.9% 10%; | ||
--secondary: 240 3.7% 15.9%; | ||
--secondary-foreground: 0 0% 98%; | ||
/* --muted: 165 10% 7.84%; */ | ||
--muted: 240 3.45% 11.37%; | ||
--muted-foreground: 240 5% 64.9%; | ||
--accent: 240 3.7% 15.9%; | ||
--accent-foreground: 0 0% 98%; | ||
/* --destructive: 0 62.8% 30.6%; */ | ||
--destructive: 356.18 70.61% 48.04%; | ||
--destructive-foreground: 0 0% 98%; | ||
--warning: 46.38 70.61% 48.04%; | ||
--warning-foreground: 120 12.5% 3.14%; | ||
/* --border: 240 3.7% 15.9%; */ | ||
--border: 240 2% 14%; | ||
--border-muted: 240 2% 14%; | ||
--input: 240 3.7% 15.9%; | ||
--ring: 240 4.9% 83.9%; | ||
--danger: 356.18 70.61% 48.04%; | ||
} | ||
} | ||
|
||
@layer base { | ||
* { | ||
@apply border-border; | ||
} | ||
body { | ||
@apply bg-background text-foreground; | ||
} | ||
} | ||
|
||
::selection { | ||
color: hsl(var(--background)); | ||
background: hsl(var(--foreground)); | ||
} | ||
|
||
.google { | ||
display: inline-block; | ||
width: 20px; | ||
height: 20px; | ||
position: relative; | ||
background-size: contain; | ||
background-repeat: no-repeat; | ||
background-position: 50%; | ||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 48 48'%3E%3Cdefs%3E%3Cpath id='a' d='M44.5 20H24v8.5h11.8C34.7 33.9 30.1 37 24 37c-7.2 0-13-5.8-13-13s5.8-13 13-13c3.1 0 5.9 1.1 8.1 2.9l6.4-6.4C34.6 4.1 29.6 2 24 2 11.8 2 2 11.8 2 24s9.8 22 22 22c11 0 21-8 21-22 0-1.3-.2-2.7-.5-4z'/%3E%3C/defs%3E%3CclipPath id='b'%3E%3Cuse xlink:href='%23a' overflow='visible'/%3E%3C/clipPath%3E%3Cpath clip-path='url(%23b)' fill='%23FBBC05' d='M0 37V11l17 13z'/%3E%3Cpath clip-path='url(%23b)' fill='%23EA4335' d='M0 11l17 13 7-6.1L48 14V0H0z'/%3E%3Cpath clip-path='url(%23b)' fill='%2334A853' d='M0 37l30-23 7.9 1L48 0v48H0z'/%3E%3Cpath clip-path='url(%23b)' fill='%234285F4' d='M48 48L17 24l-4-3 35-10z'/%3E%3C/svg%3E"); | ||
} | ||
|
||
@keyframes spin { | ||
from { | ||
transform: rotate(0deg); | ||
} | ||
to { | ||
transform: rotate(360deg); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Header } from '@/components/header' | ||
import cn from 'mxcn' | ||
import type { Metadata } from 'next' | ||
import { Inter } from 'next/font/google' | ||
import { Toaster } from 'sonner' | ||
import './globals.css' | ||
|
||
const inter = Inter({ subsets: ['latin'] }) | ||
|
||
export const metadata: Metadata = { | ||
title: 'English (CEFR) Level Assessment Bot - Langbase', | ||
description: 'Build an English (CEFR) Level Assessment Bot with ⌘ Langbase using any LLM model.', | ||
keywords: ['English', 'CEFR Level Assessment Bot', 'Langbase'] | ||
} | ||
|
||
export default function RootLayout({ | ||
children | ||
}: Readonly<{ | ||
children: React.ReactNode | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body className={cn(inter.className, 'dark bg-background')}> | ||
<div className="flex min-h-screen flex-col px-3 pr-0 pt-6"> | ||
<div className="rounded-l-[calc(var(--radius)+2px)] border border-r-0 pb-1 pl-1"> | ||
<Toaster /> | ||
<Header /> | ||
<main className="rounded-l-[calc(var(--radius)+2px)] bg-muted"> | ||
{children} | ||
</main> | ||
</div> | ||
</div> | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Chatbot } from '@/components/chatbot-page' | ||
|
||
export const runtime = 'edge' | ||
|
||
export default function ChatPage() { | ||
return <Chatbot /> | ||
} |
Oops, something went wrong.