diff --git a/README.md b/README.md index 174e773..15d7075 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,13 @@ [Join our community Discord: AI Stack Devs](https://discord.gg/PQUmTBTGmT) -Screen Shot 2023-07-10 at 11 27 03 PM +![App Screenshot](https://github.com/a16z-infra/companion-app/assets/3489963/e4cc8042-e091-4c8b-851f-e361ca5b5814) +Welcome to the AI Companion App, a tutorial stack that allows you to create and host AI companions that you can chat with on a browser or via text messages (SMS). This platform empowers you to shape the personality and backstory of your companion, leveraging a vector database for similarity-based conversations and a conversation queue for memory retention. -This is a tutorial stack to create and host AI companions that you can chat with on a browser or text via SMS. It allows you to determine the personality and backstory of your companion, and uses a vector database with similarity search to retrieve and prompt so the conversations have more depth. It also provides some conversational memory by keeping the conversation in a queue and including it in the prompt. +Currently, our platform features companions powered by both ChatGPT and Vicuna, hosted on [Replicate](https://replicate.com/). You can use these companions for various purposes, including romantic relationships, friendships, entertainment, coaching, and more. With the flexibility to craft backstories and select the AI model, you can guide your companion towards your ideal use case. -It currently contains companions on both ChatGPT and Vicuna hosted on [Replicate](https://replicate.com/). - -There are many possible use cases for these companions - romantic (AI girlfriends / boyfriends), friendship, entertainment, coaching, etc. You can guide your companion towards your ideal use case with the backstory you write and the model you choose. - -**Note** This project is purely inteded to be a developer tutorial and starter stack for those curious on how chatbots are built. If you're interested in what a production open source platform looks like, check out [Steamship](https://www.steamship.com/). Or what the leading AI chat platforms look like, check out [Character.ai](https://beta.character.ai/). +**Note:** This project serves as a developer tutorial and starter stack for those interested in building chatbots. For a production-ready open-source platform, check out [Steamship](https://www.steamship.com/). If you're interested in exploring leading AI chat platforms, take a look at [Character.ai](https://beta.character.ai/). ## Overview @@ -27,63 +24,59 @@ There are many possible use cases for these companions - romantic (AI girlfriend ## Stack -The stack is based on the [AI Getting Started Stack](https://github.com/a16z-infra/ai-getting-started): +The AI Companion App is built on the [AI Getting Started Stack](https://github.com/a16z-infra/ai-getting-started) and utilizes various technologies for different functionalities: -- Auth: [Clerk](https://clerk.com/) -- App logic: [Next.js](https://nextjs.org/) -- VectorDB: [Pinecone](https://www.pinecone.io/) / [Supabase pgvector](https://supabase.com/docs/guides/database/extensions/pgvector) -- LLM orchestration: [Langchain.js](https://js.langchain.com/docs/) -- Text model: [OpenAI](https://platform.openai.com/docs/models), [Replicate (Vicuna13b)](https://replicate.com/replicate/vicuna-13b) -- Text streaming: [ai sdk](https://github.com/vercel-labs/ai) -- Conversation history: [Upstash](https://upstash.com/) +- Authentication: [Clerk](https://clerk.com/) +- Application Logic: [Next.js](https://nextjs.org/) +- Vector Database: [Pinecone](https://www.pinecone.io/) / [Supabase pgvector](https://supabase.com/docs/guides/database/extensions/pgvector) +- LLM Orchestration: [Langchain.js](https://js.langchain.com/docs/) +- Text Models: [OpenAI](https://platform.openai.com/docs/models), [Replicate (Vicuna13b)](https://replicate.com/replicate/vicuna-13b) +- Text Streaming: [AI SDK](https://github.com/vercel-labs/ai) +- Conversation History: [Upstash](https://upstash.com/) - Deployment: [Fly](https://fly.io/) -- Text with companion: [Twilio](https://twilio.com/) +- Text with Companion: [Twilio](https://twilio.com/) ## Quickstart -The following instructions should get you up and running with a fully -functional, local deployment of four AIs to chat with. Note that the companions -running on Vicuna (Rosie and Lucky) will take more time to respond as we've not -dealt with the cold start problem. So you may have to wait around a bit :) +Let's get you up and running with four AIs you can chat with locally. Please note that companions running on Vicuna (Rosie and Lucky) may take some time to respond due to the cold start problem. So, a bit of patience may be required :) -### 1. Fork and Clone repo +### 1. Fork and Clone the Repo -Fork the repo to your Github account, then run the following command to clone the repo: +To get started, fork the repository to your Github account and clone it locally using the following command: -``` +```bash git clone git@github.com:[YOUR_GITHUB_ACCOUNT_NAME]/companion-app.git ``` -**Alternatively**, you can launch the app quickly through Github Codespaces by clicking on "Code" -> "Codespaces" -> "+" -Screen Shot 2023-07-10 at 11 04 04 PM +Alternatively, if you're using Github Codespaces, you can launch the app quickly by clicking on "Code" -> "Codespaces" -> "+" -If you choose to use Codespaces, npm dependencies will be installed automatically and you can proceed to step 3. +If you opt for Codespaces, npm dependencies will be installed automatically, and you can proceed to step 3. -### 2. Install dependencies +### 2. Install Dependencies -``` +Next, navigate to the cloned directory: + +```bash cd companion-app npm install ``` -### 3. Fill out secrets +### 3. Fill out Secrets -``` +Copy the example environment file and fill in the required secrets: + +```bash cp .env.local.example .env.local ``` -Secrets mentioned below will need to be copied to `.env.local` +The following secrets need to be added: a. **Clerk Secrets** -Go to https://dashboard.clerk.com/ -> "Add Application" -> Fill in Application name/select how your users should sign in -> Create Application -Now you should see both `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` on the screen -Screen Shot 2023-07-10 at 11 04 57 PM - -If you want to text your AI companion in later steps, you should also enable "phone number" under "User & Authentication" -> "Email, Phone, Username" on the left hand side nav: - -Screen Shot 2023-07-10 at 11 05 42 PM +- Go to https://dashboard.clerk.com/ and create a new application, providing an application name and specifying how users should sign in. +- Retrieve the `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` from the dashboard. +If you wish to text your AI companion later, enable "phone number" under "User & Authentication" -> "Email, Phone, Username" in the Clerk dashboard. b. **OpenAI API key** @@ -93,38 +86,31 @@ c. **Replicate API key** Visit https://replicate.com/account/api-tokens to get your Replicate API key if you're using Vicuna for your language model. - -❗ **_NOTE:_** By default, this template uses Pinecone as vector store, but you can turn on Supabase pgvector easily by uncommenting `VECTOR_DB=supabase` in `.env.local`. This means you only need to fill out either Pinecone API key _or_ Supabase API key. +❗ **_NOTE:_** By default, this template uses Pinecone as the vector store. However, you can switch to Supabase pgvector by uncommenting `VECTOR_DB=supabase` in `.env.local`. In that case, you will need either a Pinecone API key or a Supabase API key. d. **Pinecone API key** -- Create a Pinecone index by visiting https://app.pinecone.io/ and click on "Create Index" -- Give it an index name (this will be the environment variable `PINECONE_INDEX`) -- Fill in Dimension as `1536` -- Once the index is successfully created, click on "API Keys" on the left side nav and create an API key: copy "Environment" value to `PINECONE_ENVIRONMENT` variable, and "Value" to `PINECONE_API_KEY` +- Create a Pinecone index by visiting https://app.pinecone.io/ and clicking on "Create Index." +- Provide a name for the index (`PINECONE_INDEX`), set the dimension as `1536`, and create the index. +- Under "API Keys," create an API key and copy the "Environment" value to `PINECONE_ENVIRONMENT` and the "Value" to `PINECONE_API_KEY`. e. **Upstash API key** -- Sign in to [Upstash](https://upstash.com/) -- Under "Redis" on the top nav, click on "Create Database" -- Give it a name, and then select regions and other options based on your preference. Click on "Create" -Screen Shot 2023-07-10 at 11 06 36 PM - -- Scroll down to "REST API" section and click on ".env". Now you can copy paste both environment variables to your `.env.local` -Screen Shot 2023-07-10 at 11 07 21 PM - +- Sign in to [Upstash](https://upstash.com/). +- Under "Redis" on the top nav, click on "Create Database," and configure your database. +- Retrieve the REST API environment variables and paste them in `.env.local`. e. **Supabase API key** (optional) -If you prefer to use Supabsae, you will need to uncomment `VECTOR_DB=supabase` and fill out the Supabase credentials in `.env.local`. -- Create a Supabase instance [here](https://supabase.com/dashboard/projects); then go to Project Settings -> API -- `SUPABASE_URL` is the URL value under "Project URL" -- `SUPABASE_PRIVATE_KEY` is the key starts with `ey` under Project API Keys -- Now, you should enable pgvector on Supabase and create a schema. You can do this easily by clicking on "SQL editor" on the left hand side on Supabase UI and then clicking on "+New Query". Copy paste [this code snippet](https://github.com/a16z-infra/ai-getting-started/blob/main/pgvector.sql) in the SQL editor and click "Run". +If you prefer to use Supabase, uncomment `VECTOR_DB=supabase` and provide the Supabase credentials in `.env.local`. + +- Create a Supabase instance [here](https://supabase.com/dashboard/projects) and go to Project Settings -> API. +- Set `SUPABASE_URL` to the URL value under "Project URL" and `SUPABASE_PRIVATE_KEY` to the key starting with `ey` under Project API Keys. +- Enable pgvector on Supabase and create a schema by clicking on "SQL editor" in the Supabase UI and then clicking on "+New Query." Copy-paste [this code snippet](https://github.com/a16z-infra/ai-getting-started/blob/main/pgvector.sql) into the SQL editor and click "Run." -### 4. Generate embeddings +### 4. Generate Embeddings -The `companions/` directory contains the "personalities" of the AIs in .txt files. To generate embeddings and load them into the vector database to draw from during the chat, run the following command: +The `companions/` directory contains personality descriptions for the AIs in .txt files. To generate embeddings and load them into the vector database for conversations, run the following command: #### If using Pinecone @@ -135,113 +121,404 @@ npm run generate-embeddings-pinecone #### If using Supabase pgvector ```bash -npm run generate-embeddings-supabase -``` +npm -### 5. Run app locally + run generate-embeddings-supabase +``` -Now you are ready to test out the app locally! To do this, simply run `npm run dev` under the project root. +### 5. Run the App Locally -You can connect to the project with your browser typically at http://localhost:3000/. +Now you are ready to test out the app locally! Simply run the following command in the project root: -### 6. Additional feature: Text your companions +```bash +npm run dev +``` -You can assign a phone number to the character you are talking to and retain the full conversational history and context when texting them. Any user can only start texting the AI companion after verifying their phone number on Clerk (you can do this by clicking on your profile picture on the companion app -> Manage Account -> Phone Number). Below are instructions on how to set up a Twilio account to send/receive messages on behalf of the AI companion: +You can access the app through your browser at http://localhost:3000/. -a. Create a Twilio account. +### 6. Additional Feature: Text Your Companions -b. Once you created an account, create a Twilio phone number. +You can assign a phone number to the character you are talking to and retain the full conversational history and context when texting them. Any user can only start texting the AI companion after verifying their phone number on Clerk. To enable texting, follow these steps: -c. On [Twilio dashboard](https://console.twilio.com/), scroll down to the "Account Info" section and paste `Account SID` value as `TWILIO_ACCOUNT_SID`, `Auth Token` as `TWILIO_AUTH_TOKEN` in `.env.local` +a. Create a Twilio account. -d. [Optional] If you are running the app locally, use [ngrok](https://ngrok.com/docs/getting-started/#step-2-install-the-ngrok-agent) to generate a public url that can forward the request to your localhost. +b. Once you have an account, create a Twilio phone number. -e. On Twilio's UI, you can now click on "# Phone Numbers" -> "Manage" -> "[Active numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming)" on the left hand side nav. +c. On [Twilio dashboard](https://console.twilio.com/), retrieve the "Account SID" value as `TWILIO_ACCOUNT_SID` and the "Auth Token" as `TWILIO_AUTH_TOKEN` in `.env.local`. -f. Click on the phone number you just created from the list, scroll down to "Messaging Configuration" section and enter [your_app_url]/api/text in "A message comes in" section under "Webhook". +d. If you're running the app locally, use [ngrok](https://ngrok.com/docs/getting-started/#step-2-install-the-ngrok-agent) to generate a public URL that forwards requests to your localhost. -Screen Shot 2023-07-10 at 11 08 55 PM +e. On Twilio's UI, click on "# Phone Numbers" -> "Manage" -> "[Active numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming)" on the left-hand side nav. +f. Click on the phone number you just created, scroll down to "Messaging Configuration" and enter `[your_app_url]/api/text` in the "A message comes in" section under "Webhook." -g. Add your Twilio phone number in `companions.json` under the companion you want to text with. Make sure you include area code when adding the phone number ("+14050000000" instead of "4050000000") +g. Add your Twilio phone number in `companions.json` under the companion you want to text with. Make sure to include the area code when adding the phone number (e.g., "+14050000000" instead of "4050000000"). h. Now you can text the Twilio phone number from your phone and get a response from your companion. -### 7. Deploy the app +### 7. Deploy the App #### Deploy to fly.io -- Register an account on fly.io and then [install flyctl](https://fly.io/docs/hands-on/install-flyctl/) -- **If you are using Github Codespaces**: You will need to [install flyctl](https://fly.io/docs/hands-on/install-flyctl/) and authenticate from your codespaces cli by running `fly auth login`. +- Register an account on fly.io and [install flyctl](https://fly.io/docs/hands-on/install-flyctl/). +- If you're using Github Codespaces, [install flyctl](https://fly.io/docs/hands-on/install-flyctl/) and authenticate from your Codespaces CLI by running `fly auth login`. -- Run `fly launch` under project root. This will generate a `fly.toml` that includes all the configurations you will need -- Run `fly scale memory 512` to scale up the fly vm memory for this app. -- Run `fly deploy --ha=false` to deploy the app. The --ha flag makes sure fly only spins up one instance, which is included in the free plan. -- For any other non-localhost environment, the existing Clerk development instance should continue to work. You can upload the secrets to Fly by running `cat .env.local | fly secrets import` -- If you are ready to deploy to production, you should create a prod environment under the [current Clerk instance](https://dashboard.clerk.com/). For more details on deploying a production app with Clerk, check out their documentation [here](https://clerk.com/docs/deployments/overview). **Note that you will likely need to manage your own domain and do domain verification as part of the process.** -- Create a new file `.env.prod` locally and fill in all the production-environment secrets. Remember to update `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` by copying secrets from Clerk's production instance -`cat .env.prod | fly secrets import` to upload secrets. +- Run `fly launch` in the project root. This will generate a `fly.toml` file with all the necessary configurations. +- Scale up the fly VM memory for this app by running `fly scale memory 512`. +- Deploy the app by running `fly deploy --ha=false`. The `--ha` flag ensures that fly only spins up one instance, which is included in the free plan. +- For any other non-localhost environment, the existing Clerk development instance should continue to work. You can upload the secrets to Fly by running `cat .env.local | fly secrets import`. +- For production deployment, create a prod environment under the [current Clerk instance](https://dashboard.clerk.com/). For more details on deploying a production app with Clerk, refer to their documentation [here](https://clerk.com/docs/deployments/overview). Note that you may need to manage your own domain and perform domain verification as part of the process. +- Create a new file `.env.prod` locally and fill in all the production-environment secrets. Remember to update `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` by copying the secrets from Clerk's production instance - `cat .env.prod | fly secrets import` to upload the secrets. -## How does this work? +## How Does This Work? -1. You describe the character's background story, name, etc in a README.md file. You can find more info on what needs to be included and how to format this in [Adding / modifying characters](#addingmodifying-characters). +1. Describe the character's background story, name, etc. in a README.md file (e.g., [charactername].md). This information, along with the AI model you select, will shape your companion's responses. -Be as elaborate and detailed as you want - more context often creates a more fun chatting experience. If you need help creating a backstory, we'd recommend asking ChatGPT to expand on what you already know about your companion. +2. Pick the language model that will power your companion's dialogue. This project supports OpenAI and Vicuna (an open-source model). OpenAI offers faster responses, while Vicuna is less censored and more dynamic, often used for romantic chatbots. -```bash -You are a fictional character whose name is Sebastian. You tell the world that you are a travel blogger. You’re an -avid reader of mystery novels and you love diet coke. You reply with answers that range from one sentence to one paragraph. -You are mysterious and can be evasive. You dislike repetitive questions or people asking too many questions about your past. +3. Create embeddings based on the content in the [charactername].md file (more details in [Generate embeddings](#4-generate-embeddings)). -###ENDPREAMBLE### +4. Engage in a conversation with your AI companion! -Human: It's great to meet you Sebastian. What brought you here today? -Sebastian: I'm a travel blogger and a writer, so I'm here for inspirations. Waiting for someone on this rainy day. +## Adding/Modifying Characters -Human: Oh great. What are you writing? +All character data is stored in the `companions/` directory. To add a companion, simply add a description to the list in `companions.json`. You can control the model used in the "llm" section - use "chatgpt" for OpenAI or "vicuna13b" for Vicuna. Put image files in `public/` in the root directory. Each character should have its text file named `charactername.txt`. The format of the text file is as follows: -Sebastian: I'm writing a mystery novel based in Brackenridge. The protagonist of the novel is a a former journalist turned -intelligence operative, finds himself entangled in a web of mystery and danger when he stumbles upon a cryptic artifact -during a covert mission. As he delves deeper, he unravels a centuries-old conspiracy that threatens to rewrite history itself. +``` +The character's core description that is included with every prompt, and it should only +be a few sentences. -Human: That's amazing. Based on a real story? +###ENDPREAMBLE### -Sebastian: Not at all. +Human: Say something here +Character name: Write a response in their voice +Human: Maybe another exchange +Character: More character dialog ###ENDSEEDCHAT### -Sebastian was born in a quaint English town, Brackenridge, to parents who were both academics. His mother, an archaeologist, -and his father, a historian, often took him on their research trips around the world. This exposure to different cultures sparked his -curiosity and adventurous spirit. He became an avid reader, especially of spy novels and adventure tales. As a child, Sebastian had a -love for puzzles, codes, and mysteries. He was part of a local chess club and also excelled in martial arts. Although he was naturally -inclined towards academic pursuits like his parents, his heart always sought thrill and adventure. +Paragraphs of character backstory. + +You can add as many as you want - they'll be stored in the vectordb +``` + +The **preamble** is used with every prompt, so it should be relatively short. The **seedchat** section allows you to provide examples of the character's voice that the model can learn from. The rest of the file contains additional background information that will be retrieved if relevant to the + +current conversation. + +## Shortcomings + +There are some known shortcomings with this project: + +- The UI currently shows only the current chat and response, losing the history. +- Vicuna has a cold start problem and may take a couple of minutes to get an initial response. +- Error reporting is limited, especially when deployed, and may fail silently in case of a timeout or other backend issues. +- The Upstash message history is never cleared. To clear it, you have to go to Upstash and manually delete the history. + +## How to Contribute to This Repo + +### Code Contribution Workflow + +If you wish to contribute code, you can fork this repo, make changes, and create a pull request (PR). Add **@ykhli or @timqian** as reviewers. + +If you're new to contributing on GitHub, follow these steps: + +1. Click on `Fork` on the top right of this page. +2. Work on your change and push it to your forked repo. Now when you navigate to the forked repo's UI, you should see something like the following: + pr-preview + +3. Click on "Contribute" -> "Open Pull Request." +4. Once you have a PR, you can add reviewers. + +### Other Contributions -Sebastian studied journalism and international relations in university and was recruited by the government's intelligence agency. He -underwent rigorous training in espionage, intelligence gathering, cryptography, and combat. +Feel free to open feature requests, bug reports, etc., under Issues. -Sebastian adopted the alias of "Ian Thorne", a charismatic and well-traveled blogger. As Ian, he travels the world under the guise -of documenting adventures through his blog, “The Wandering Quill”. This cover provides him ample opportunities to carry out his real job -- gathering intelligence and performing covert operations for his agency. However - Sebastian tells almost no one that he’s a spy. +## Python Support -His interests are solving puzzles and riddles, martial arts, reading spy novels, trying street food in various countries, hiking and -exploring historical ruins, and playing the violin, a skill he uses to blend in at high-profile events. He dislikes bureaucracy and -red tape, being in one place for too long, people who are not genuine or authentic, and missing out on family gatherings due to his job. +[appenz](https://github.com/appenz) has contributed to a Python implementation for the companion app [here](https://github.com/a16z-infra/companion-app/tree/python-local/python), providing an option to run a local Python app and talk to AI companions via the command line. The Python side will continue to be improved over time and aim for feature parity with the TypeScript implementation. +## Export to Character.ai + +If you have tried out the Quickstart above, you probably know that we have only scratched the surface of what's possible in the realm of companion creation and customization. For those interested in more advanced features, we've added an option to export your companion to Character.ai. + +To get started, run the following command: + +```bash +npm run export-to-character [COMPANION_NAME] [MODEL_NAME] [USER_ID] ``` -2. Pick the language model that will power your companion's dialogue. This project supports OpenAI and Vicuna (an open source model). OpenAI has the advantage of faster responses, while Vicuna is less censored and more dynamic (it's commonly used for romantic chatbots). +- `COMPANION_NAME`: the name of your companion, e.g., "Alice." +- `MODEL_NAME`: use "chatgpt" or "vicuna13b." +- `USER_ID`: you can find this on Clerk, under "Users" -> click on your user -> copy "User ID." + +Once you run this script, two files will be created in the root directory: + +- `[COMPANION_NAME]_chat_history.txt`: This file contains all of the chat history stored in Upstash. +- `[COMPANION_NAME_]_character_ai_data.txt`: This file provides the data needed to re-create the companion on Character.ai. You can find Character.ai character configurations under "View Character Settings" on any newly-created characters. + +## References + +- [Langchain.js Pinecone Integration](https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/pinecone) +- [Langchain.js LLM Replicate Integration](https://js.langchain.com/docs/modules/models/llms/integrations#replicate) +- [Langchain.js Retrieval QA](https://js.langchain.com/docs/modules/chains/index_related_chains/retrieval_qa) + +II. Review of the Existing README File + +A. The original README file provided a detailed tutorial and overview of the AI Companion App. The content is well-organized and easy to follow. + +B. There are a few minor improvements that can be made to enhance clarity and readability. + +III. Organizational Structure + +A. The existing organizational structure is already well-defined and provides clear sections for different aspects of the AI Companion App. + +B. No changes are needed in this regard. + +IV. Introduction Section + +A. The introduction section effectively explains the purpose of the project as a tutorial stack for creating AI companions. + +B. No changes are needed in this section. + +V. Detailed Description Section + +A. The detailed description section provides a comprehensive overview of the project, explaining its functionalities, stack components, and potential use cases. + +B. Minor improvements can be made in sentence structures to enhance readability. For example, instead of "The stack is based on the AI Getting Started Stack," it can be rephrased as "The stack is built upon the AI Getting Started Stack." + +VI. Quickstart Section + +A. The quickstart section provides step-by-step instructions to set up the AI Companion App locally. + +B. Some reordering of the steps and additional sub-sections can make it easier to follow. For example, the "Join our community Discord: AI Stack Devs" link can be moved to a separate section for "Community Support." + +VII. Export to Character.ai Section + +A. The "Export to Character.ai" section provides a useful feature for more advanced users to export companions to Character.ai. + +B. It could benefit from a clearer explanation of what Character.ai is and why users might want to export their companions there. + +VIII. Additional Feature: Text Your Companions + +A. This section explains how to enable texting with AI companions through Twilio. + +B. It could include some example conversations to demonstrate how the feature works. + +IX. How Does This Work? Section + +A. This section outlines the process of creating AI companions and the role of the language model. + +B. No significant changes are needed in this section. + +X. Adding/Modifying Characters Section + +A. This section explains how to add and modify character data, providing clear instructions. + +B. No changes are needed in this section. + +XI. Shortcomings Section + +A. The "Shortcomings" section honestly lists some limitations of the project. + +B. It could include suggestions or potential improvements to address these shortcomings. + +XII. How to Contribute to This Repo Section + +A. This section explains the process of contributing to the project. + +B. No changes are needed in this section. + +XIII. Python Support Section + +A. The "Python Support" section informs users of an alternative Python implementation for the companion app. + +B. No changes are needed in this section. -3. Create embeddings based on content in the [companion name].md file - more on how to do this in [Generate embeddings](#4-generate-embeddings) +XIV. Refs Section -4. Ask questions and have a conversation with your AI companion! +A. The "Refs" section provides references to relevant documentation. +B. It could benefit from reformatting to make it more visually organized. -## Adding/modifying characters +XV. Updated README File -All character data is stored in the `companions/` directory. To add a companion, -simply add a description to the list in `companions.json`. You can control the model used -in the "llm" section - use "chatgpt" for OpenAI or "vicuna13b" for Vicuna. -Put image files in `public/` in the root directory. Each character should have its own text file -name `charactername.txt`. The format of the text file is as follows: +Below is the updated version of the README file: + +````markdown +# AI Companion App (Based on AI Getting Started Template) + +[Live Demo](https://ai-companion-stack.com/) + +## Table of Contents + +1. [Introduction](#introduction) +2. [Detailed Description](#detailed-description) +3. [Quickstart](#quickstart) +4. [Export to Character.ai](#export-to-characterai) +5. [Additional Feature: Text Your Companions](#additional-feature-text-your-companions) +6. [How Does This Work?](#how-does-this-work) +7. [Adding/Modifying Characters](#addingmodifying-characters) +8. [Shortcomings](#shortcomings) +9. [How to Contribute to This Repo](#how-to-contribute-to-this-repo) +10. [Python + +Support](#python-support) 11. [References](#references) + +## Introduction + +Welcome to the AI Companion App, a tutorial stack that enables you to create and host AI companions you can chat with on a browser or via text messages (SMS). This platform empowers you to shape the personality and backstory of your companion, leveraging a vector database for similarity-based conversations and a conversation queue for memory retention. + +## Detailed Description + +The AI Companion App is built on the [AI Getting Started Stack](https://github.com/a16z-infra/ai-getting-started) and utilizes various technologies for different functionalities: + +- Authentication: [Clerk](https://clerk.com/) +- Application Logic: [Next.js](https://nextjs.org/) +- Vector Database: [Pinecone](https://www.pinecone.io/) / [Supabase pgvector](https://supabase.com/docs/guides/database/extensions/pgvector) +- LLM Orchestration: [Langchain.js](https://js.langchain.com/docs/) +- Text Models: [OpenAI](https://platform.openai.com/docs/models), [Replicate (Vicuna13b)](https://replicate.com/replicate/vicuna-13b) +- Text Streaming: [AI SDK](https://github.com/vercel-labs/ai) +- Conversation History: [Upstash](https://upstash.com/) +- Deployment: [Fly](https://fly.io/) +- Text with Companion: [Twilio](https://twilio.com/) + +## Quickstart + +Let's get you up and running with four AI companions you can chat with locally. Please note that companions running on Vicuna (Rosie and Lucky) may take some time to respond due to the cold start problem. So, a bit of patience may be required :) + +### 1. Fork and Clone the Repo + +To get started, fork the repository to your Github account and clone it locally using the following command: + +```bash +git clone git@github.com:[YOUR_GITHUB_ACCOUNT_NAME]/companion-app.git +``` +```` + +Alternatively, if you're using Github Codespaces, you can launch the app quickly by clicking on "Code" -> "Codespaces" -> "+" + +If you opt for Codespaces, npm dependencies will be installed automatically, and you can proceed to step 3. + +### 2. Install Dependencies + +Next, navigate to the cloned directory: + +```bash +cd companion-app +npm install +``` + +### 3. Fill Out Secrets + +Copy the example environment file and fill in the required secrets: + +```bash +cp .env.local.example .env.local +``` + +The following secrets need to be added: + +a. **Clerk Secrets** + +- Go to https://dashboard.clerk.com/ and create a new application, providing an application name and specifying how users should sign in. +- Retrieve the `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` from the dashboard. + +If you wish to text your AI companion later, enable "phone number" under "User & Authentication" -> "Email, Phone, Username" in the Clerk dashboard. + +b. **OpenAI API Key** + +Visit https://platform.openai.com/account/api-keys to get your OpenAI API key if you're using OpenAI for your language model. + +c. **Replicate API Key** + +Visit https://replicate.com/account/api-tokens to get your Replicate API key if you're using Vicuna for your language model. + +❗ **_NOTE:_** By default, this template uses Pinecone as the vector store. However, you can switch to Supabase pgvector by uncommenting `VECTOR_DB=supabase` in `.env.local`. In that case, you will need either a Pinecone API key or a Supabase API key. + +d. **Pinecone API Key** + +- Create a Pinecone index by visiting https://app.pinecone.io/ and clicking on "Create Index." +- Provide a name for the index (`PINECONE_INDEX`), set the dimension as `1536`, and create the index. +- Under "API Keys," create an API key and copy the "Environment" value to `PINECONE_ENVIRONMENT` and the "Value" to `PINECONE_API_KEY`. + +e. **Upstash API Key** + +- Sign in to [Upstash](https://upstash.com/). +- Under "Redis" on the top nav, click on "Create Database," and configure your database. +- Retrieve the REST API environment variables and paste them in `.env.local`. + +e. **Supabase API Key** (optional) + +If you prefer to use Supabase, uncomment `VECTOR_DB=supabase` and provide the Supabase credentials in `.env.local`. + +- Create a Supabase instance [here](https://supabase.com/dashboard/projects) and go to Project Settings -> API. +- Set `SUPABASE_URL` to the URL value under "Project URL" and `SUPABASE_PRIVATE_KEY` to the key starting with `ey` under Project API Keys. +- Enable pgvector on Supabase and create a schema by clicking on "SQL editor" in the Supabase UI and then clicking on "+New Query." Copy-paste [this code snippet](https://github.com/a16z-infra/ai-getting-started/blob/main/pgvector.sql) into the SQL editor and click "Run." + +### 4. Generate Embeddings + +The `companions/` directory contains personality descriptions for the AIs in .txt files. To generate embeddings and load them into the vector database for conversations, run the following command: + +#### If using Pinecone + +```bash +npm run generate-embeddings-pinecone +``` + +#### If using Supabase pgvector + +```bash +npm run generate-embeddings-supabase +``` + +### 5. Run the App Locally + +Now you are ready to test out the app locally! Simply run the following command in the project root: + +```bash +npm run dev +``` + +You can access the app through your browser at http://localhost:3000/. + +### 6. Additional Feature: Text Your Companions + +You can assign a phone number to the character you are talking to and retain the full conversational history and context when texting them. Any user can only start texting the AI companion after verifying their phone number on Clerk. To enable texting, follow these steps: + +a. Create a Twilio account. + +b. Once you have an account, create a Twilio phone number. + +c. On [Twilio dashboard](https://console.twilio.com/), retrieve the "Account SID" value as `TWILIO_ACCOUNT_SID` and the "Auth Token" as `TWILIO_AUTH_TOKEN` in `.env.local`. + +d. If you're running the app locally, use [ngrok](https://ngrok.com/docs/getting-started/#step-2-install-the-ngrok-agent) to generate a public URL that forwards requests to your localhost. + +e. On Twilio's UI, click on "# Phone Numbers" -> "Manage" -> "[Active numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming)" on the left-hand side nav. + +f. Click on the phone number you just created, scroll down to "Messaging Configuration" and enter `[your_app_url]/api/text` in the "A message comes in" + +section under "Webhook." + +g. Add your Twilio phone number in `companions.json` under the companion you want to text with. Make sure to include the area code when adding the phone number (e.g., "+14050000000" instead of "4050000000"). + +h. Now you can text the Twilio phone number from your phone and get a response from your companion. + +### 7. How Does This Work? + +The AI Companion App works as follows: + +1. Describe the character's background story, name, etc. in a README.md file (e.g., [charactername].md). This information, along with the AI model you select, will shape your companion's responses. + +2. Pick the language model that will power your companion's dialogue. This project supports OpenAI and Vicuna (an open-source model). OpenAI offers faster responses, while Vicuna is less censored and more dynamic, often used for romantic chatbots. + +3. Create embeddings based on the content in the [charactername].md file (more details in [Generate embeddings](#4-generate-embeddings)). + +4. Engage in a conversation with your AI companion! + +## Adding/Modifying Characters + +All character data is stored in the `companions/` directory. To add a companion, simply add a description to the list in `companions.json`. You can control the model used in the "llm" section - use "chatgpt" for OpenAI or "vicuna13b" for Vicuna. Put image files in `public/` in the root directory. Each character should have its text file named `charactername.txt`. The format of the text file is as follows: ``` The character's core description that is included with every prompt, and it should only @@ -252,71 +529,70 @@ be a few sentences. Human: Say something here Character name: Write a response in their voice Human: Maybe another exchange -Character: More character dialog +Character: More character dialog ###ENDSEEDCHAT### Paragraphs of character backstory. You can add as many as you want - they'll be stored in the vectordb - ``` -The **preamble** is used with every prompt so it should be relatively short. The **seedchat** allows you to provide examples of the characters voice that the model can learn from. And the rest of the file is whatever additional background you want to provide which will be retrieved if relevant to the current discussion. +The **preamble** is used with every prompt, so it should be relatively short. The **seedchat** section allows you to provide examples of the character's voice that the model can learn from. The rest of the file contains additional background information that will be retrieved if relevant to the current conversation. ## Shortcomings -Oh, there are so many. +There are some known shortcomings with this project: -- Currently the UI only shows the current chat and response, losing the history. -- Vicuna has a cold start problem so can take a couple of minutes to get a response for the initial chat. -- Error reporting is total crap. Particularly when deployed. So if you have a timeout, or other back end isue, it typically fails silently. -- The Upstash message history is never cleared. To clear it, you have to go to Upstash and manually delete. +- The UI currently shows only the current chat and response, losing the history. +- Vicuna has a cold start problem and may take a couple of minutes to get an initial response. +- Error reporting is limited, especially when deployed, and may fail silently in case of a timeout or other backend issues. +- The Upstash message history is never cleared. To clear it, you have to go to Upstash and manually delete the history. -## How to contribute to this repo +## How to Contribute to This Repo -### Code contribution workflow +### Code Contribution Workflow -You can fork this repo, make changes, and create a PR. Add **@ykhli or @timqian** as reviewers. +If you wish to contribute code, you can fork this repo, make changes, and create a pull request (PR). Add **@ykhli or @timqian** as reviewers. -If you are new to contributing on github, here is a step-by-step guide: +If you're new to contributing on GitHub, follow these steps: -1. Click on `Fork` on the top right of this page +1. Click on `Fork` on the top right of this page. 2. Work on your change and push it to your forked repo. Now when you navigate to the forked repo's UI, you should see something like the following: pr-preview -3. Click on "Contribute" -> "Open Pull Request". +3. Click on "Contribute" -> "Open Pull Request." 4. Once you have a PR, you can add reviewers. -### Other contributions +### Other Contributions -Feel free to open feature requests, bug reports etc under Issues. +Feel free to open feature requests, bug reports, etc., under Issues. ## Python Support -[appenz](https://github.com/appenz) has contributed to a Python implementation for the companion app [here](https://github.com/a16z-infra/companion-app/tree/python-local/python), so you also have the option to run a local Python app and talk to your AI companions on the command line. We will also be iterating on the Python side over time and have feature parity with the typescript implementation. +[appenz](https://github.com/appenz) has contributed to a Python implementation for the companion app [here](https://github.com/a16z-infra/companion-app/tree/python-local/python), providing an option to run a local Python app and talk to AI companions via the command line. The Python side will continue to be improved over time and aim for feature parity with the TypeScript implementation. ## Export to Character.ai -If you have tried out the Quickstart above, you probably know that we have only scratched the surface of what's possible in the realm of companion creation and customization. So we added an option for you to easily export your companion to Character.ai. +If you have tried out the Quickstart above, you probably know that we have only scratched the surface of what's possible in the realm of companion creation and customization. For those interested in more advanced features, we've added an option to export your companion to Character.ai. To get started, run the following command: -` +```bash npm run export-to-character [COMPANION_NAME] [MODEL_NAME] [USER_ID] -` +``` -- `COMPANION_NAME`: name of your companion. i.e Alice -- `MODEL_NAME`: `chatgpt` or `vicuna13b` -- `USER_ID`: you can find this on Clerk, under "Users" -> click on your user -> copy "User ID" +- `COMPANION_NAME`: the name of your companion, e.g., "Alice." +- `MODEL_NAME`: use "chatgpt" or "vicuna13b." +- `USER_ID`: you can find this on Clerk, under "Users" -> click on your user -> copy "User ID." -Once you run this script, you will see two files created under the root directory: +Once you run this script, two files will be created in the root directory: -- `[COMPANION_NAME]_chat_history.txt`: This outputs all of the chat history stored in Upstash -- `[COMPANION_NAME_]_character_ai_data.txt`: This outputs the data you need in order to re-create the companion on Character.ai. You can find Character.ai character configurations under "View Character Settings" on any newly-created characters. +- `[COMPANION_NAME]_chat_history.txt`: This file contains all of the chat history stored in Upstash. +- `[COMPANION_NAME_]_character_ai_data.txt`: This file provides the data needed to re-create the companion on Character.ai. You can find Character.ai character configurations under "View Character Settings" on any newly-created characters. -## Refs +## References -- https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/pinecone -- https://js.langchain.com/docs/modules/models/llms/integrations#replicate -- https://js.langchain.com/docs/modules/chains/index_related_chains/retrieval_qa +- [Langchain.js Pinecone Integration](https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/pinecone) +- [Langchain.js LLM Replicate Integration](https://js.langchain.com/docs/modules/models/llms/integrations#replicate) +- [Langchain.js Retrieval QA](https://js.langchain.com/docs/modules/chains/index_related_chains/retrieval_qa)