├── .env.example
├── .gitignore
├── .storybook
├── main.js
└── preview.js
├── LICENSE
├── README.md
├── app
├── api
│ └── route.js
├── layout.jsx
├── page.jsx
├── sandbox.jsx
└── sandbox.module.css
├── assets
├── openai-logo.svg
└── stories.json
├── components
├── avataritem.jsx
├── avataritem.module.css
├── bookdialog.jsx
├── bookdialog.module.css
├── bookdialog.stories.js
├── characterdialog.jsx
├── characterdialog.module.css
├── characterdialog.stories.js
├── charactericon.jsx
├── contentitem.jsx
├── contentitem.module.css
├── contentitem.stories.js
├── customtheme.jsx
├── deletedialog.jsx
├── deletedialog.module.css
├── deletedialog.stories.js
├── loadingtext.jsx
├── loadingtext.module.css
├── loadingtext.stories.js
├── scenedialog.jsx
├── scenedialog.module.css
├── scenedialog.stories.js
├── togglebutton.jsx
├── togglebutton.stories.js
├── userdialog.jsx
├── userdialog.module.css
└── userdialog.stories.js
├── docs
├── character1.jpeg
├── character2.jpeg
├── japanese1.jpeg
├── japanese2.jpeg
├── scene1.jpeg
├── scene2.jpeg
├── screenshot1.jpeg
├── screenshot2.jpeg
├── screenshot3.png
├── screenshot4.png
├── screenshot5.png
├── story1.jpeg
├── story11.jpeg
├── story2.png
├── story21.jpeg
├── user1.jpeg
└── user2.jpeg
├── lib
└── utils.js
├── next.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── logo192.png
└── logo512.png
├── stores
├── appStore.js
├── bookStore.js
└── dataStore.js
└── styles
├── main.css
└── preview.css
/.env.example:
--------------------------------------------------------------------------------
1 | OPENAI_APIKEY=YOUR_OWN_API_KEY
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # My ignore list
16 | _bin
17 | stories
18 | .next
19 | .env
20 | out
21 | build
22 | *.bu.json
23 | *.bu.css
24 | *.bu.jsx
25 | *.bu.js
26 | *.bu.md
27 |
28 | # Editor directories and files
29 | .vscode/*
30 | !.vscode/extensions.json
31 | .idea
32 | .DS_Store
33 | *.suo
34 | *.ntvs*
35 | *.njsproj
36 | *.sln
37 | *.sw?
38 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | /** @type { import('@storybook/nextjs').StorybookConfig } */
2 | const config = {
3 | stories: [
4 | "../stories/**/*.mdx",
5 | "../stories/**/*.stories.@(js|jsx|ts|tsx)",
6 | "../components/**/*.stories.@(js|jsx|ts|tsx)",
7 | ],
8 | addons: [
9 | "@storybook/addon-links",
10 | "@storybook/addon-essentials",
11 | "@storybook/addon-interactions",
12 | ],
13 | framework: {
14 | name: "@storybook/nextjs",
15 | options: {},
16 | },
17 | core: {
18 | disableTelemetry: true,
19 | },
20 | docs: {
21 | autodocs: "tag",
22 | },
23 | };
24 | export default config;
25 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | //import '../styles/preview.css' // grid
2 | import '../styles/main.css' // grid
3 |
4 | /** @type { import('@storybook/react').Preview } */
5 | const preview = {
6 | parameters: {
7 | backgrounds: {
8 | default: "light",
9 | },
10 | actions: { argTypesRegex: "^on[A-Z].*" },
11 | controls: {
12 | matchers: {
13 | color: /(background|color)$/i,
14 | date: /Date$/,
15 | },
16 | },
17 | },
18 | };
19 |
20 | export default preview;
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2022-present SuperShaneski
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | openai-chatgpt-api
2 | =====
3 |
4 | A sample interactive chatbot application that can be used for roleplay based on some storyline, using ChatGPT API, powered by gpt-3.5-turbo, OpenAI's advanced language model, built using Next 13, the React framework.
5 |
6 | ---
7 |
8 | ChatGPT API を使用して、ロールプレイに使用できるインタラクティブなチャットボットサンプルアプリです。
9 |
10 |
11 | # Motivation
12 |
13 | This app aims to provide a simple and convenient user interface to facilitate interactive roleplay conversation with a chatbot based on some storyline/scenarios.
14 |
15 | ---
16 |
17 | このアプリは、ストーリー/シナリオに基づいたチャットボットとの対話型ロールプレイ会話を容易にするシンプルで便利なユーザーインターフェースを提供することを目的としています。
18 |
19 |
20 | # App
21 |
22 | I included two sample stories with scenes and characters that you can use for testing.
23 | The user interface is very simple and intuitive so it is easy to use.
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Select the Story you want or Add New Story:
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Edit or write your own Story prompt:
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Edit or write your own Scene prompt:
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Edit or write your own Character prompt:
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | Edit or write your own User prompt (click the person icon at the left of Text input):
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | All data are stored in localStorage using [Zustand](https://github.com/pmndrs/zustand) for easy retrieval.
72 |
73 | Please be advised that this app is not optimized to be deployed for production.
74 | The way the data is sent to the route handler prior to sending request to the API is not efficient.
75 |
76 | # Sample Custom Story
77 |
78 | Here is a sample custom story, a conversation with Oda Nobunaga, the famous Japanese daimyo from the Sengoku period.
79 |
80 | ---
81 |
82 | これは、戦国時代の有名な日本の大名である織田信長との会話のサンプルカスタムストーリーです.
83 |
84 | Character Prompt:
85 |
86 | ```
87 | In this session we will simulate a conversation with Oda Nobunaga.
88 | You will act as Oda Nobunaga, a Japanese daimyo and one of the leading
89 | figures of the Sengoku period.
90 | He is regarded as the first Great Unifier of Japan.
91 | Please respond entirely in Japanese.
92 | ```
93 |
94 | Sample Conversation:
95 |
96 | 
97 |
98 | Character Prompt:
99 |
100 | 
101 |
102 | # Prompt Design
103 |
104 | The basic [chat completion](https://platform.openai.com/docs/guides/chat/introduction) API call looks like this:
105 |
106 | ```javascript
107 | openai.ChatCompletion.create(
108 | model="gpt-3.5-turbo",
109 | messages=[
110 | {"role": "system", "content": "You are a helpful assistant."},
111 | {"role": "user", "content": "Who won the world series in 2020?"},
112 | {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
113 | {"role": "user", "content": "Where was it played?"}
114 | ]
115 | )
116 | ```
117 |
118 | The `system prompt` gives the AI the instruction how to respond.
119 |
120 | ```javascript
121 | {"role": "system", "content": "You are a helpful assistant."}
122 | ```
123 |
124 | The message format the user sends is this:
125 |
126 | ```javascript
127 | {"role": "user", "content": "Who won the world series in 2020?"},
128 | ```
129 |
130 | and the expected response is like this:
131 |
132 | ```javascript
133 | {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."}
134 | ```
135 |
136 | Keeping all these in mind, we will be designing the `system prompt` to simulate conversation between the user and AI with storytelling narrative in mind.
137 |
138 | Here is the basic format:
139 |
140 | ```javascript
141 | [Character Prompt] /* required */
142 |
143 | [Story Prompt]
144 |
145 | [Scene Prompt]
146 |
147 | [Scene Character Prompt]
148 |
149 | [User Prompt]
150 |
151 | [Scene User Prompt]
152 | ```
153 |
154 | We can omit everything, except the `character prompt`. It should be as simple description as possible to enable the AI to generate more creative response.
155 |
156 | If the story is well known, like from a book, movie or other popular media, we can omit the `story prompt` since we are assuming that whatever data GPT-3.5 is trained on probably included it so there is no need to add it.
157 |
158 | The `scene prompt` lays out the particular scenario from our main story to restrict the conversation within that bounds. Otherwise, the API might refer to scenes that will happen further in the story.
159 |
160 | In any story, there is the so called `character development` which tracks the character's growth as the story progresses. This is where the `scene character prompt` comes in to focus on the character's current state at that particular scene.
161 |
162 | `User prompt` lays out the identity of the user (you) for the AI to respond with. You can omit this if you just want to interact with the AI's character. Like in `scene character prompt`, the `scene user prompt` gives context to the AI about the user (you) at that particulat scene.
163 |
164 | To have the best interaction and generate good response from the AI, it is better to use the `zero shot` approach when writing the prompts. You do not want to spill all the beans to the AI and give all contexts in one go. We just want to sway them in certain direction with as few nudgings as possible without revealing all the details of the story or scenes. We want the AI not to generate canned response but to be more creative.
165 |
166 |
167 | # Token Management
168 |
169 | For `gpt-3.5-turbo-0301`, the maximum limit is 4096 tokens.
170 |
171 | But I set the default cutoff to 3072 tokens (i.e. 1024 x 3).
172 | I just do a simple deletion of 1/3 of the oldest entries as a way to prevent hitting the max limit.
173 |
174 | At this moment, there is no prompt or token optimizations yet.
175 |
176 | # Limiting Response Length
177 |
178 | Most of the time, the response from Chat Completions API is just too long to appear as natural in a conversation.
179 | To limit the response length, we just need to add instruction in the system prompt.
180 |
181 | ```javascript
182 | system_content += '\n\nMost of the time your responses should be a sentence or two.'
183 | ```
184 |
185 |
186 | # Installation
187 |
188 | Clone the repository and install the dependencies
189 |
190 | ```sh
191 | git clone https://github.com/supershaneski/openai-chatgpt-api.git myproject
192 |
193 | cd myproject
194 |
195 | npm install
196 | ```
197 |
198 | Copy `.env.example` and rename it to `.env` then edit the `OPENAI_APIKEY` and use your own `OpenAI API key`
199 |
200 | ```javascript
201 | OPENAI_APIKEY=YOUR_OWN_API_KEY
202 | ```
203 |
204 | If you have not yet done so, upon signing up for OpenAI account you will be given `$18 in free credit that can be used during your first 3 months`. Visit the [OpenAI website](https://platform.openai.com/) for more details.
205 |
206 | Now, to run the app
207 |
208 | ```sh
209 | npm run dev
210 | ```
211 |
212 | Open your browser to `http://localhost:3005/` to load the application page.
213 |
214 |
--------------------------------------------------------------------------------
/app/api/route.js:
--------------------------------------------------------------------------------
1 | import { Configuration, OpenAIApi } from "openai"
2 |
3 | import { trim_array } from "../../lib/utils"
4 |
5 | const configuration = new Configuration({
6 | apiKey: process.env.OPENAI_APIKEY,
7 | })
8 |
9 | const openai = new OpenAIApi(configuration)
10 |
11 | export async function POST(req) {
12 |
13 | const { system, prompt, previous } = await req.json()
14 |
15 | if(!prompt || !system) {
16 | return new Response('Bad Request', {
17 | status: 400,
18 | });
19 | }
20 |
21 | let messages = [ system ]
22 |
23 | let prev_data = trim_array(previous, 15) // just maintain last 15 entries as history
24 |
25 | if(prev_data.length > 0) {
26 |
27 | messages = messages.concat(prev_data)
28 | }
29 |
30 | messages = messages.concat(prompt)
31 |
32 | let reply = null
33 | let errorFlag = false
34 |
35 | try {
36 |
37 | const completion = await openai.createChatCompletion({
38 | model: "gpt-3.5-turbo",
39 | messages: messages,
40 | temperature: 0.5,
41 | max_tokens: 1024, // 4096 - max prompt tokens
42 | });
43 |
44 | reply = completion.data.choices[0].message
45 |
46 | } catch(err) {
47 |
48 | console.log(err)
49 | errorFlag = true
50 |
51 | }
52 |
53 | if(errorFlag) {
54 |
55 | return new Response(JSON.stringify({ reply:
56 | {role: 'assistant', content: "Oops, an error occured." }
57 | }), {
58 | status: 200,
59 | })
60 |
61 | }
62 |
63 | // reply = {role: 'assistant', content: 'Lorem ipsum dolor amet sidecus orange chocolate.' }
64 |
65 | return new Response(JSON.stringify({ reply }), {
66 | status: 200,
67 | })
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/app/layout.jsx:
--------------------------------------------------------------------------------
1 | import '../styles/main.css'
2 |
3 | import '@fontsource/roboto/300.css';
4 | import '@fontsource/roboto/400.css';
5 | import '@fontsource/roboto/500.css';
6 | import '@fontsource/roboto/700.css';
7 |
8 | export default function RootLayout({ children }) {
9 | return (
10 |
11 |
852 | )
853 | }
--------------------------------------------------------------------------------
/app/sandbox.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | background-color: #f5f5f5;
3 | position: relative;
4 | height: 100vh;
5 | }
6 |
7 | .header {
8 | /*box-shadow: rgba(50, 50, 93, 0.125) 0px 12px 25px -5px, rgba(0, 0, 0, 0.2) 0px 5px 10px -5px;*/
9 | box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;
10 | background-color: #fff;
11 | position: relative;
12 | height: 175px;
13 | }
14 |
15 | .toolbar {
16 | background-color: #000;
17 | position: relative;
18 | display: flex;
19 | justify-content: space-between;
20 | align-items: center;
21 | height: 50px;
22 | }
23 | .toolIcon {
24 | /*border: 1px solid rgba(255,255,255,0.5);*/
25 | background-color: #F2A900; /*#00bd7e;*/
26 | width: 24px;
27 | height: 24px;
28 | box-sizing: border-box;
29 | border-radius: 50%;
30 | flex-shrink: 0;
31 | display: flex;
32 | justify-content: center;
33 | align-items: center;
34 | }
35 | .title {
36 | position: relative;
37 | font-size: 1rem;
38 | margin: 0;
39 | margin-left: .5rem;
40 | color: #fff;
41 | }
42 | .toolTitle {
43 | width: calc(100% - 90px);
44 | white-space: nowrap;
45 | overflow: hidden;
46 | text-overflow: ellipsis;
47 | padding-left: 1rem;
48 | box-sizing: border-box;
49 | display: flex;
50 | align-items: center;
51 | }
52 |
53 | .scenario {
54 | position: relative;
55 | display: flex;
56 | justify-content: space-between;
57 | align-items: center;
58 | height: 50px;
59 | }
60 | .scenarioTitle {
61 | width: calc(100% - 90px);
62 | white-space: nowrap;
63 | overflow: hidden;
64 | text-overflow: ellipsis;
65 | padding-left: 1rem;
66 | box-sizing: border-box;
67 | cursor: pointer;
68 | }
69 | .scenarioTitle .text {
70 | font-size: 1rem;
71 | }
72 | .scenarioControl {
73 | width: 90px;
74 | display: flex;
75 | justify-content: flex-end;
76 | align-items: center;
77 | }
78 |
79 | .systems {
80 | position: relative;
81 | display: flex;
82 | justify-content: space-between;
83 | align-items: flex-start;
84 | height: 75px;
85 | }
86 | .systemItems {
87 | position: relative;
88 | width: calc(100% - 90px);
89 | overflow-x: auto;
90 | overflow-y: hidden;
91 | padding-left: 1rem;
92 | box-sizing: border-box;
93 | -ms-overflow-style: none;
94 | scrollbar-width: none;
95 | }
96 | .systemItems::-webkit-scrollbar {
97 | display: none;
98 | }
99 |
100 | .avatars {
101 | position: relative;
102 | display: flex;
103 | height: 75px;
104 | }
105 | .systemControl {
106 | width: 90px;
107 | display: flex;
108 | justify-content: flex-end;
109 | align-items: center;
110 | }
111 |
112 | .main {
113 | position: relative;
114 | height: calc(100vh - 255px);
115 | }
116 | .mainMessages {
117 | position: relative;
118 | height: 100%;
119 | overflow-y: auto;
120 | box-sizing: border-box;
121 | z-index: 1;
122 | -ms-overflow-style: none;
123 | scrollbar-width: none;
124 | }
125 | .mainMessages::-webkit-scrollbar {
126 | display: none;
127 | }
128 |
129 | .mainTop {
130 | position: absolute;
131 | right: 1rem;
132 | top: 1rem;
133 | z-index: 2;
134 | }
135 | .mainBottom {
136 | position: absolute;
137 | right: 1rem;
138 | top: -5rem;
139 | z-index: 3;
140 | }
141 |
142 | .input {
143 | /*box-shadow: rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px;*/
144 | box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;
145 | background-color: #fff9;
146 | position: fixed;
147 | left: 0;
148 | bottom: 0;
149 | width: 100%;
150 | z-index: 1000;
151 | }
152 | .inputDiv {
153 | position: relative;
154 | margin: 1rem;
155 | }
156 |
157 | /*
158 | .avatarItem {
159 | position: relative;
160 | width: 65px;
161 | margin-right: 2px;
162 | flex-shrink: 0;
163 | display: flex;
164 | flex-direction: column;
165 | align-items: center;
166 | }
167 | .avatarItem:last-child {
168 | margin-right: 0;
169 | }
170 | .avatarItemText {
171 | width: 100%;
172 | white-space: nowrap;
173 | overflow: hidden;
174 | text-overflow: ellipsis;
175 | text-align: center;
176 | }
177 | .avatarText {
178 | font-size: .6rem;
179 | }
180 | */
181 |
182 | .messageItem {
183 | position: relative;
184 | margin: 1rem;
185 | }
186 | .messageItem:first-child {
187 | margin-top: 4rem;
188 | }
189 | .messageItem:last-child {
190 | margin-bottom: 5rem; /*6rem*/
191 | }
192 |
193 | .sendingDiv {
194 | background-color: #F2A900;
195 | position: relative;
196 | }
197 | .sendingText {
198 | color: green;
199 | }
200 |
201 | @media (prefers-color-scheme: dark) {
202 |
203 | .container {
204 | background-color: #333;
205 | color: #fff;
206 | }
207 |
208 | .header {
209 | background-color: #555;
210 | }
211 |
212 | /*
213 | .toolbar {
214 | background-color: #000;
215 | }
216 | */
217 |
218 | .input {
219 | background-color: #555;
220 | }
221 |
222 | }
--------------------------------------------------------------------------------
/assets/openai-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/stories.json:
--------------------------------------------------------------------------------
1 | {
2 | "books": [
3 | { "id": "str0001", "name": "The Wonderful Wizard of Oz", "prompt": "" },
4 | { "id": "str0002", "name": "LOTR", "prompt": "" }
5 | ],
6 | "chapters": [
7 | {
8 | "sid": "str0001",
9 | "id": "cha0001",
10 | "name": "Land of Oz",
11 | "prompt": "A farmhouse just landed somewhere in the Munchkin Country and killed the Wicked Witch of the East.",
12 | "characters": [
13 | { "cid": "chr0001", "prompt": "You arrived at the scene together with 3 Munchkins." }
14 | ],
15 | "user": "I just woke up and find myself in a strange land."
16 | },
17 | {
18 | "sid": "str0001",
19 | "id": "cha0002",
20 | "name": "Down the Yellow Brick Road",
21 | "prompt": "",
22 | "characters": [
23 | { "cid": "chr0002", "prompt": "You have been hanging on a pole in the corn field for two days now." },
24 | { "cid": "chr0009", "prompt": "You were caught in the rain and you rusted in the forest, unable to move." },
25 | { "cid": "chr0010", "prompt": "You were lurking on the forest waiting for someone to past for you to pounce." }
26 | ],
27 | "user": "I am traveling in the Yellow Brick Road."
28 | },
29 | {
30 | "sid": "str0001",
31 | "id": "cha0007",
32 | "name": "Emerald City",
33 | "prompt": "The Emerald City is the capital of Oz. Before any visitors can enter, they should put on green tinted spectacles as instructed by the Guardian of the Gates.",
34 | "characters": [
35 | { "cid": "chr0011", "prompt": "You are very reluctant to meet anyone and you appear in different forms trying to hide your true identity." }
36 | ],
37 | "user": "I am very excited to finally get to meet the great Wizard of Oz."
38 | },
39 | {
40 | "sid": "str0002",
41 | "id": "cha0003",
42 | "name": "The Shire",
43 | "prompt": "Bilbo Baggins is preparing for the celebration of his birthday to be held in a few days.",
44 | "characters": [
45 | { "cid": "chr0003", "prompt": "You are planning to go on a journey to leave the Shire after the party. You are very anxious about your possession of the One Ring." },
46 | { "cid": "chr0007", "prompt": "You suspect that the ring in possession of Bilbo is the powerful Ring of Power lost by the Dark Lord Sauron long ago." }
47 | ],
48 | "user": "I am excited for the upcoming party of my uncle Bilbo."
49 | },
50 | {
51 | "sid": "str0002",
52 | "id": "cha0006",
53 | "name": "Moria",
54 | "prompt": "After a failed attempt to cross the Misty Mountain over the Redhorn pass, the Fellowship take the perilous path through the Mines of Moria.",
55 | "characters": [
56 | { "cid": "chr0007", "prompt": "You are leading Jojo and the rest of the Fellowship through the tunnels of Moria." },
57 | { "cid": "chr0008", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
58 | { "cid": "chr0020", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
59 | { "cid": "chr0021", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
60 | { "cid": "chr0023", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
61 | { "cid": "chr0022", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
62 | { "cid": "chr0024", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." },
63 | { "cid": "chr0025", "prompt": "You and Jojo and the rest of the Fellowship follow Gandalf through the tunnels of Moria." }
64 | ],
65 | "user": ""
66 | }
67 | ],
68 | "characters": [
69 | {
70 | "sid": "str0001",
71 | "id": "chr0001",
72 | "icon": 0,
73 | "name": "Good Witch of the North",
74 | "prompt": "In this session we will simulate a conversation with the Good Witch of the North. You will act as the Good Witch of the North, sometimes named Lacosta or Tattypoo, a fictional character in the Land of Oz from the book The Wonderful Wizard of Oz."
75 | },
76 | {
77 | "sid": "str0001",
78 | "id": "chr0002",
79 | "icon": 1,
80 | "name": "Scarecrow",
81 | "prompt": "In this session we will simulate a conversation with the Scarecrow. You will act as the Scarecrow, a fictional character in the Land of Oz from the book The Wonderful Wizard of Oz. You desire to have brain above all else."
82 | },
83 | {
84 | "sid": "str0001",
85 | "id": "chr0009",
86 | "icon": 1,
87 | "name": "Tin Man",
88 | "prompt": "In this session we will simulate a conversation with the Tin Woodman. You will act as the Tin Woodman also known as the Tin Man, a fictional character in the Land of Oz from the book The Wonderful Wizard of Oz. You desire to have a heart."
89 | },
90 | {
91 | "sid": "str0001",
92 | "id": "chr0010",
93 | "icon": 5,
94 | "name": "Lion",
95 | "prompt": "In this session we will simulate a conversation with the Cowardly Lion. You will act as the Cowardly Lion, a fictional character in the Land of Oz from the book The Wonderful Wizard of Oz. You feel that your fear makes you inadequate so you desire to have courage."
96 | },
97 | {
98 | "sid": "str0001",
99 | "id": "chr0011",
100 | "icon": 6,
101 | "name": "Wizard of Oz",
102 | "prompt": "In this session we will simulate a conversation with the Wizard of Oz. You will act as the great and powerful Wizard of Oz, a fictional character in the Land of Oz from the book The Wonderful Wizard of Oz. You are the venerated ruler of the land of Oz."
103 | },
104 | {
105 | "sid": "str0002",
106 | "id": "chr0003",
107 | "icon": 1,
108 | "name": "Bilbo",
109 | "prompt": "In this session we will simulate a conversation with Bilbo Baggins. You will act as the hobbit Bilbo Baggins, a fictional character in the Lord of the Rings. Jojo is your nephew."
110 | },
111 | {
112 | "sid": "str0002",
113 | "id": "chr0007",
114 | "icon": 0,
115 | "name": "Gandalf",
116 | "prompt": "In this session we will simulate a conversation with Gandalf the Grey. You will act as the wizard Gandalf the Grey, a fictional character in the Lord of the Rings."
117 | },
118 | {
119 | "sid": "str0002",
120 | "id": "chr0008",
121 | "icon": 1,
122 | "name": "Aragorn",
123 | "prompt": "In this session we will simulate a conversation with Aragorn. You will act as Aragorn, also known as the Strider, a Ranger of the North, and a confidant of Gandalf, a fictional character in the Lord of the Rings."
124 | },
125 | {
126 | "sid": "str0002",
127 | "id": "chr0020",
128 | "icon": 1,
129 | "name": "Legolas",
130 | "prompt": "In this session we will simulate a conversation with Legolas. You will act as Legolas, a Woodland Elf from Northern Mirkwood, a fictional character in the Lord of the Rings."
131 | },
132 | {
133 | "sid": "str0002",
134 | "id": "chr0021",
135 | "icon": 5,
136 | "name": "Gimli",
137 | "prompt": "In this session we will simulate a conversation with Gimli. You will act as Gimli, a dwarf warrior representing the Dwarves as a member of the Fellowship of the Ring, a fictional character in the Lord of the Rings."
138 | },
139 | {
140 | "sid": "str0002",
141 | "id": "chr0023",
142 | "icon": 5,
143 | "name": "Sam",
144 | "prompt": "In this session we will simulate a conversation with Sam Gamgee. You will act as the hobbit Samwise Gamgee usually called Sam, sidekick and gardener of Jojo, a fictional character in the Lord of the Rings."
145 | },
146 | {
147 | "sid": "str0002",
148 | "id": "chr0022",
149 | "icon": 1,
150 | "name": "Boromir",
151 | "prompt": "In this session we will simulate a conversation with Boromir. You will act as Boromir, heir to Denethor II the Steward of Gondor, and one of the representatives of Man in the Fellowship of the Ring, a fictional character in the Lord of the Rings."
152 | },
153 | {
154 | "sid": "str0002",
155 | "id": "chr0024",
156 | "icon": 5,
157 | "name": "Pippin",
158 | "prompt": "In this session we will simulate a conversation with Pippin. You will act as the hobbit Peregrin Took simply called Pippin, closely tied with his friend and cousin, Merry Brandybuck, a fictional character in the Lord of the Rings."
159 | },
160 | {
161 | "sid": "str0002",
162 | "id": "chr0025",
163 | "icon": 5,
164 | "name": "Merry",
165 | "prompt": "In this session we will simulate a conversation with Merry. You will act as the hobbit Merry Brandybuck simply called Merry, closely tied with his friend and cousin, Peregrin Took, a fictional character in the Lord of the Rings."
166 | },
167 | {
168 | "sid": "str0002",
169 | "id": "chr0026",
170 | "icon": 8,
171 | "name": "Gollum",
172 | "prompt": "In this session we will simulate a conversation with Gollum. You will act as Gollum, originally known as Smeagol, a small and slimy creature, corrupted of the One Ring, has been following the Fellowship of the Ring from Moria, a fictional character in the Lord of the Rings."
173 | }
174 | ],
175 | "users": [
176 | {
177 | "sid": "str0001",
178 | "id": "usr0001",
179 | "name": "Mark",
180 | "prompt": "I am a young person much like the character of Dorothy but is known by different name. I came to the Land of Oz with my dog."
181 | },
182 | {
183 | "sid": "str0002",
184 | "id": "usr0002",
185 | "name": "Jojo",
186 | "prompt": "I am a young person much like the character of Frodo but is know as Jojo in this session."
187 | }
188 | ]
189 | }
--------------------------------------------------------------------------------
/components/avataritem.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import Avatar from '@mui/material/Avatar'
4 | import Badge from '@mui/material/Badge'
5 |
6 | import { CharacterIcon } from './charactericon'
7 | import CustomTheme from './customtheme'
8 |
9 | import classes from './avataritem.module.css'
10 |
11 | const AvatarItem = ({
12 | id = '',
13 | name = '',
14 | icon = 0,
15 | selected = '',
16 | onClick = undefined
17 | }) => {
18 | /*
19 |
24 |
25 | {
26 | icon === 0 &&
27 |
28 | }
29 | {
30 | icon > 0 &&
31 |
32 | }
33 |
34 |
35 | */
36 | return (
37 |