Skip to content

Commit 68782e5

Browse files
committed
First.
0 parents  commit 68782e5

22 files changed

+7051
-0
lines changed

.devcontainer/devcontainer.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"image": "mcr.microsoft.com/devcontainers/javascript-node:1.0.7-18-bullseye",
3+
"features": {
4+
"git-lfs": "latest"
5+
},
6+
"customizations": {
7+
"vscode": {
8+
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"],
9+
"settings": {
10+
"editor.formatOnSave": true,
11+
"editor.defaultFormatter": "esbenp.prettier-vscode"
12+
}
13+
}
14+
}
15+
}

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# The ChatBotKit Secret Token
2+
CHATBOTKIT_API_SECRET=

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
next-env.d.ts

.prettierrc.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"plugins": ["@trivago/prettier-plugin-sort-imports"],
3+
"semi": false,
4+
"trailingComma": "es5",
5+
"singleQuote": true,
6+
"printWidth": 80,
7+
"tabWidth": 2,
8+
"useTabs": false,
9+
"bracketSpacing": true,
10+
"bracketSameLine": false,
11+
"arrowParens": "always",
12+
"importOrder": [
13+
".css$",
14+
"^core-js-pure",
15+
"^jest",
16+
"^@/styles",
17+
"^dotenv",
18+
"^react",
19+
"^react-*",
20+
"^next/*",
21+
"^@/",
22+
"^:/",
23+
"^#/",
24+
"^[./]",
25+
"^@",
26+
"^."
27+
],
28+
"importOrderSeparation": true,
29+
"importOrderSortSpecifiers": true
30+
}

.vscode/extensions.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"recommendations": [
3+
"esbenp.prettier-vscode",
4+
"dbaeumer.vscode-eslint",
5+
"github.copilot"
6+
]
7+
}

.vscode/settings.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib",
3+
"typescript.enablePromptUseWorkspaceTsdk": false,
4+
"editor.tabSize": 2,
5+
"editor.rulers": [80],
6+
"editor.defaultFormatter": "esbenp.prettier-vscode",
7+
"editor.formatOnSave": true,
8+
"terminal.integrated.scrollback": 100000,
9+
"editor.codeActionsOnSave": {
10+
"source.fixAll.eslint": "explicit"
11+
},
12+
"githubPullRequests.remotes": ["origin"],
13+
"files.autoSave": "off",
14+
"files.associations": {
15+
"*.xml": "html",
16+
"*.svg": "html"
17+
}
18+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 ChatBotKit
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Generative UI Template for Next.js / ChatBotKit / JS
2+
3+
This repository is a template to quickly start your next Generative UI project using Node.js, ChatBotKit and JavaScript.
4+
5+
## Technology Stack
6+
7+
- **ChatBotKit SDK**: For building the chatbot logic and handling conversation flow.
8+
- **React**: For UI components that interact with the user, such as forms for capturing appointment details and slot selection.
9+
- **Next.js**: The application environment.
10+
11+
## Setup
12+
13+
1. Ensure you have Node.js installed.
14+
2. Clone this repository.
15+
3. Install dependencies by running npm install.
16+
4. Set the `CHATBOTKIT_API_SECRET` environment variable with your ChatBotKit API secret.
17+
5. Optionally, set the `CHATBOTKIT_MODEL` environment variable to specify the model used for conversation (default is GPT-3.5 Turbo).
18+
19+
## Usage
20+
21+
Run the development server:
22+
23+
```bash
24+
npm run dev
25+
```
26+
27+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
28+
29+
## Learn More
30+
31+
To learn more about ChatBotKit and relevent SDKs look at the following resources:
32+
33+
- [ChatBotKit Documentation](https://chatbotkit.com/docs) - learn about ChatBotKit
34+
- [ChatBotKit JavaScript SDKs](https://github.com/chatbotkit/node-sdk) - learn about used SDKs
35+
36+
## Deployment
37+
38+
The easiest way to deploy this Next.js app is to use the [Vercel Platform](https://vercel.com).
39+
40+
## Contributing
41+
42+
Contributions to enhance the chatbot's functionality or address issues are welcome. Please follow the standard pull request process for contributions.
43+
44+
## License
45+
46+
This project is licensed under the MIT License - see the LICENSE file for details.

actions/conversation.jsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use server'
2+
3+
import Component01 from '@/components/functions/Component01'
4+
5+
import { streamComplete } from '@chatbotkit/react/actions/complete'
6+
import { ChatBotKit } from '@chatbotkit/sdk'
7+
8+
const cbk = new ChatBotKit({
9+
secret: process.env.CHATBOTKIT_API_SECRET,
10+
})
11+
12+
export async function complete({ messages }) {
13+
return streamComplete({
14+
client: cbk.conversation,
15+
16+
// The backstory is the heart of the conversation. It provides the context
17+
// and rules for the conversational AI agent to follow. In this example, the
18+
// backstory is a simple appointment booking system for a virtual assistant.
19+
20+
backstory: `ADD BACKSTORY HERE`,
21+
22+
// We allow configuration of the model to be used for the conversation by
23+
// setting the CHATBOTKIT_MODEL environment variable. The default model is
24+
// GPT-3.5 Turbo.
25+
26+
model: process.env.CHATBOTKIT_MODEL || 'gpt-3.5-turbo',
27+
28+
// Pass the messages to the conversation.
29+
30+
messages,
31+
32+
// Pass a list of functions that the AI agent can call to interact with.
33+
34+
functions: [
35+
{
36+
name: 'function01',
37+
description: 'Description of function01',
38+
parameters: {},
39+
handler: async () => {
40+
return {
41+
result: {
42+
status: 'success',
43+
data: {},
44+
},
45+
}
46+
},
47+
},
48+
49+
{
50+
name: 'function02',
51+
description: 'Description of function02',
52+
parameters: {
53+
type: 'object',
54+
properties: {
55+
param1: {
56+
type: 'string',
57+
},
58+
param2: {
59+
type: 'number',
60+
},
61+
},
62+
required: ['param1'],
63+
},
64+
handler: async ({ param1, param2 }, { controllers }) => {
65+
controllers.continuation.abort()
66+
67+
return {
68+
children: <Component01 param1={param1} param2={param2} />, // MAGIC
69+
result: {
70+
status: 'waiting for user input',
71+
},
72+
}
73+
},
74+
},
75+
],
76+
})
77+
}

app/globals.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;

app/layout.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import './globals.css'
2+
3+
export default function Layout({ children }) {
4+
return (
5+
<html lang="en">
6+
<body>{children}</body>
7+
</html>
8+
)
9+
}

app/page.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { complete } from '@/actions/conversation'
2+
import ChatArea from '@/components/ChatArea'
3+
import '@/components/functions'
4+
5+
import ConversationManager from '@chatbotkit/react/components/ConversationManager'
6+
7+
export default function Page() {
8+
return (
9+
<ConversationManager endpoint={complete}>
10+
<ChatArea />
11+
</ConversationManager>
12+
)
13+
}

components/ChatArea.jsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use client'
2+
3+
import { useContext } from 'react'
4+
5+
import { ChatInput, ChatMessage, ConversationContext } from '@chatbotkit/react'
6+
7+
import clsx from 'clsx'
8+
9+
export function UserMessage({ text, children, ...props }) {
10+
return (
11+
<div {...props} className="flex space-x-2 items-end justify-end">
12+
{text ? (
13+
<ChatMessage
14+
className="bg-white text-gray-900 border border-gray-900 rounded-lg shadow-md p-4 prose"
15+
text={text}
16+
/>
17+
) : null}
18+
{children}
19+
</div>
20+
)
21+
}
22+
23+
export function BotMessage({ text, children, ...props }) {
24+
return (
25+
<div {...props} className="flex space-x-2 items-end">
26+
{text ? (
27+
<ChatMessage
28+
className="bg-white text-gray-900 border border-gray-900 rounded-lg shadow-md p-4 prose"
29+
text={text}
30+
/>
31+
) : null}
32+
{children}
33+
</div>
34+
)
35+
}
36+
37+
export default function ChatArea() {
38+
const {
39+
thinking,
40+
41+
text,
42+
setText,
43+
44+
message,
45+
messages,
46+
47+
submit,
48+
} = useContext(ConversationContext)
49+
50+
return (
51+
<div className="my-10 mx-auto w-full max-w-2xl bg-white rounded-xl border border-gray-900 shadow-xl p-4 flex flex-col gap-4">
52+
{messages.length ? (
53+
<div className="flex flex-col gap-4">
54+
{messages
55+
.filter(({ type }) => ['user', 'bot'].includes(type))
56+
.map(({ id, type, text, children }, index, messages) => {
57+
const disableInteractivity = index < messages.length - 1
58+
59+
switch (type) {
60+
case 'user':
61+
return <UserMessage key={id} text={text} />
62+
63+
case 'bot':
64+
return (
65+
<BotMessage key={id} text={text}>
66+
{children ? (
67+
<div
68+
className={clsx(
69+
'transition-all duration-300 ease-in-out w-full',
70+
{
71+
'opacity-40 pointer-events-none':
72+
disableInteractivity,
73+
}
74+
)}
75+
>
76+
{children}
77+
</div>
78+
) : null}
79+
</BotMessage>
80+
)
81+
}
82+
})}
83+
{message ? <BotMessage key={message.id} text={message.text} /> : null}
84+
{thinking ? <BotMessage key="thinking" text="● ● ●" /> : null}
85+
</div>
86+
) : null}
87+
<ChatInput
88+
className="px-3 py-2 bg-white border border-gray-900 rounded-md focus:ring-2 focus:ring-gray-900 focus:outline-none resize-none"
89+
value={text}
90+
onChange={(e) => setText(e.target.value)}
91+
onSubmit={submit}
92+
placeholder="Your message..."
93+
/>
94+
</div>
95+
)
96+
}

0 commit comments

Comments
 (0)