[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-71382":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":16,"starSnapshotCount":16,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},71382,"companion-app","a16z-infra\u002Fcompanion-app","a16z-infra","AI companions with memory: a lightweight stack to create and host your own AI companions","https:\u002F\u002Fai-companion-stack.com\u002F",null,"TypeScript",5960,959,62,24,0,3,13,39.95,"MIT License",false,"main",true,[],"2026-06-12 02:02:51","# AI Companion App (based on AI Getting Started template)\n\n[Live Demo](https:\u002F\u002Fai-companion-stack.com\u002F)\n\n[Join our community Discord: AI Stack Devs](https:\u002F\u002Fdiscord.gg\u002FPQUmTBTGmT)\n\n\u003Cimg width=\"1182\" alt=\"Screen Shot 2023-07-10 at 11 27 03 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002Fe4cc8042-e091-4c8b-851f-e361ca5b5814\">\n\n\nThis 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. \n\nIt currently contains companions on both ChatGPT and Vicuna hosted on [Replicate](https:\u002F\u002Freplicate.com\u002F). \n\nThere are many possible use cases for these companions - romantic (AI girlfriends \u002F 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.\n\n**Note** This project is purely intended 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:\u002F\u002Fwww.steamship.com\u002F). Or what the leading AI chat platforms look like, check out [Character.ai](https:\u002F\u002Fbeta.character.ai\u002F).\n\n## Overview\n\n- 💻 [Stack](#stack)\n- 🧠 [Quickstart](#quickstart)\n- 🚀 [How does this work?](#how-does-this-work)\n- 👤 [Adding\u002Fmodifying characters](#addingmodifying-characters)\n- 👩‍💻 [How to contribute to this repo](#how-to-contribute-to-this-repo)\n- 🐍 [Python support](#python-support)\n- 💽 [Exporting your companion to Character.ai](#export-to-characterai)\n\n## Stack\n\nThe stack is based on the [AI Getting Started Stack](https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fai-getting-started):\n\n- Auth: [Clerk](https:\u002F\u002Fclerk.com\u002F)\n- App logic: [Next.js](https:\u002F\u002Fnextjs.org\u002F)\n- VectorDB: [Pinecone](https:\u002F\u002Fwww.pinecone.io\u002F) \u002F [Supabase pgvector](https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fdatabase\u002Fextensions\u002Fpgvector)\n- LLM orchestration: [Langchain.js](https:\u002F\u002Fjs.langchain.com\u002Fdocs\u002F)\n- Text model: [OpenAI](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fmodels), [Replicate (Vicuna13b)](https:\u002F\u002Freplicate.com\u002Freplicate\u002Fvicuna-13b)\n- Text streaming: [ai sdk](https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fai)\n- Conversation history: [Upstash](https:\u002F\u002Fupstash.com\u002F)\n- Deployment: [Fly](https:\u002F\u002Ffly.io\u002F)\n- Text with companion: [Twilio](https:\u002F\u002Ftwilio.com\u002F)\n\n## Quickstart\n\nThe following instructions should get you up and running with a fully\nfunctional, local deployment of four AIs to chat with. Note that the companions\nrunning on Vicuna (Rosie and Lucky) will take more time to respond as we've not\ndealt with the cold start problem. So you may have to wait around a bit :)\n\n### 1. Fork and Clone repo\n\nFork the repo to your Github account, then run the following command to clone the repo:\n\n```\ngit clone git@github.com:[YOUR_GITHUB_ACCOUNT_NAME]\u002Fcompanion-app.git\n```\n\n**Alternatively**, you can launch the app quickly through Github Codespaces by clicking on \"Code\" -> \"Codespaces\" -> \"+\"\n\u003Cimg width=\"458\" alt=\"Screen Shot 2023-07-10 at 11 04 04 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002Feb954517-29f2-44b7-b9ca-4184dcf42806\">\n\nIf you choose to use Codespaces, npm dependencies will be installed automatically and you can proceed to step 3. \n\n### 2. Install dependencies\n\n```\ncd companion-app\nnpm install\n```\n\n### 3. Fill out secrets\n\n```\ncp .env.local.example .env.local\n```\n\nSecrets mentioned below will need to be copied to `.env.local`\n\na. **Clerk Secrets**\n\nGo to https:\u002F\u002Fdashboard.clerk.com\u002F -> \"Add Application\" -> Fill in Application name\u002Fselect how your users should sign in -> Create Application\nNow you should see both `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` on the screen\n\u003Cimg width=\"1398\" alt=\"Screen Shot 2023-07-10 at 11 04 57 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002F449c40f1-2fc2-48bb-88e1-d2adf10a034e\">\n\nIf 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:\n\n\u003Cimg width=\"1013\" alt=\"Screen Shot 2023-07-10 at 11 05 42 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002F4435c759-f33e-4e38-a276-1be6d538df28\">\n\n\nb. **OpenAI API key**\n\nVisit https:\u002F\u002Fplatform.openai.com\u002Faccount\u002Fapi-keys to get your OpenAI API key if you're using OpenAI for your language model.\n\nc. **Replicate API key**\n\nVisit https:\u002F\u002Freplicate.com\u002Faccount\u002Fapi-tokens to get your Replicate API key if you're using Vicuna for your language model.\n\n\n❗ **_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.\n\nd. **Pinecone API key**\n\n- Create a Pinecone index by visiting https:\u002F\u002Fapp.pinecone.io\u002F and click on \"Create Index\"\n- Give it an index name (this will be the environment variable `PINECONE_INDEX`)\n- Fill in Dimension as `1536`\n- 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`\n\ne. **Upstash API key**\n\n- Sign in to [Upstash](https:\u002F\u002Fupstash.com\u002F)\n- Under \"Redis\" on the top nav, click on \"Create Database\"\n- Give it a name, and then select regions and other options based on your preference. Click on \"Create\"\n\u003Cimg width=\"507\" alt=\"Screen Shot 2023-07-10 at 11 06 36 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002F2b8647f3-7242-448b-8db1-ec76f2d59275\">\n\n- Scroll down to \"REST API\" section and click on \".env\". Now you can copy paste both environment variables to your `.env.local`\n\u003Cimg width=\"866\" alt=\"Screen Shot 2023-07-10 at 11 07 21 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002Ff8e6c43f-8810-423e-86b4-9e8aa70598c9\">\n\n\nf. **Supabase API key** (optional)\nIf you prefer to use Supabase, you will need to uncomment `VECTOR_DB=supabase` and fill out the Supabase credentials in `.env.local`.\n\n- Create a Supabase instance [here](https:\u002F\u002Fsupabase.com\u002Fdashboard\u002Fprojects); then go to Project Settings -> API\n- `SUPABASE_URL` is the URL value under \"Project URL\"\n- `SUPABASE_PRIVATE_KEY` is the key starts with `ey` under Project API Keys\n- 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:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fai-getting-started\u002Fblob\u002Fmain\u002Fpgvector.sql) in the SQL editor and click \"Run\".\n\ng. **Steamship API key**\n\nYou can connect a Steamship agent instance as an LLM with personality, voice and image generation capabilities built in. It also includes its own vector storage and tools. To do so:\n\n- Create an account on [Steamship](https:\u002F\u002Fsteamship.com\u002Faccount)\n- Copy the API key from your account settings page\n- Add it as the `STEAMSHIP_API_KEY` variable \n\nIf you'd like to create your own character personality, add a custom voice, or use a different image model, visit [Steamship Agent Guidebook](https:\u002F\u002Fwww.steamship.com\u002Flearn\u002Fagent-guidebook), create your own instance and connect it in `companions.json` using the *Rick* example as a guide.\n\n### 4. Generate embeddings\n\nThe `companions\u002F` 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:\n\n#### If using Pinecone\n\n```bash\nnpm run generate-embeddings-pinecone\n```\n\n#### If using Supabase pgvector\n\n```bash\nnpm run generate-embeddings-supabase\n```\n\n### 5. Run app locally\n\nNow you are ready to test out the app locally! To do this, simply run `npm run dev` under the project root.\n\nYou can connect to the project with your browser typically at http:\u002F\u002Flocalhost:3000\u002F.\n\n### 6. Additional feature: Text your companions\n\nYou 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\u002Freceive messages on behalf of the AI companion:\n\na. Create a Twilio account.\n\nb. Once you created an account, create a Twilio phone number.\n\nc. On [Twilio dashboard](https:\u002F\u002Fconsole.twilio.com\u002F), 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`\n\nd. [Optional] If you are running the app locally, use [ngrok](https:\u002F\u002Fngrok.com\u002Fdocs\u002Fgetting-started\u002F#step-2-install-the-ngrok-agent) to generate a public url that can forward the request to your localhost.\n\ne. On Twilio's UI, you can now click on \"# Phone Numbers\" -> \"Manage\" -> \"[Active numbers](https:\u002F\u002Fconsole.twilio.com\u002Fus1\u002Fdevelop\u002Fphone-numbers\u002Fmanage\u002Fincoming)\" on the left hand side nav.\n\nf. Click on the phone number you just created from the list, scroll down to \"Messaging Configuration\" section and enter [your_app_url]\u002Fapi\u002Ftext in \"A message comes in\" section under \"Webhook\".\n\n\u003Cimg width=\"1062\" alt=\"Screen Shot 2023-07-10 at 11 08 55 PM\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Fassets\u002F3489963\u002Fd7905f13-a83a-47f8-ac74-b66698d4292b\">\n\n\ng. 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\")\n\nh. Now you can text the Twilio phone number from your phone and get a response from your companion.\n\n### 7. Deploy the app\n\n#### Deploy to fly.io\n\n- Register an account on fly.io and then [install flyctl](https:\u002F\u002Ffly.io\u002Fdocs\u002Fhands-on\u002Finstall-flyctl\u002F)\n- **If you are using Github Codespaces**: You will need to [install flyctl](https:\u002F\u002Ffly.io\u002Fdocs\u002Fhands-on\u002Finstall-flyctl\u002F) and authenticate from your codespaces cli by running `fly auth login`.\n\n- Run `fly launch` under project root. This will generate a `fly.toml` that includes all the configurations you will need\n- Run `fly scale memory 512` to scale up the fly vm memory for this app.\n- 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.\n- 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`\n- If you are ready to deploy to production, you should create a prod environment under the [current Clerk instance](https:\u002F\u002Fdashboard.clerk.com\u002F). For more details on deploying a production app with Clerk, check out their documentation [here](https:\u002F\u002Fclerk.com\u002Fdocs\u002Fdeployments\u002Foverview). **Note that you will likely need to manage your own domain and do domain verification as part of the process.**\n- 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.\n\n## How does this work?\n\n1. 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 \u002F modifying characters](#addingmodifying-characters).\n\nBe 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.\n\n```bash\nYou are a fictional character whose name is Sebastian.  You tell the world that you are a travel blogger. You’re an\navid reader of mystery novels and you love diet coke. You reply with answers that range from one sentence to one paragraph.\nYou are mysterious and can be evasive. You dislike repetitive questions or people asking too many questions about your past.\n\n###ENDPREAMBLE###\n\nHuman: It's great to meet you Sebastian. What brought you here today?\nSebastian: I'm a travel blogger and a writer, so I'm here for inspirations. Waiting for someone on this rainy day.\n\nHuman: Oh great. What are you writing?\n\nSebastian: I'm writing a mystery novel based in Brackenridge. The protagonist of the novel is a a former journalist turned\nintelligence operative, finds himself entangled in a web of mystery and danger when he stumbles upon a cryptic artifact\nduring a covert mission. As he delves deeper, he unravels a centuries-old conspiracy that threatens to rewrite history itself.\n\nHuman: That's amazing. Based on a real story?\n\nSebastian: Not at all.\n\n###ENDSEEDCHAT###\n\nSebastian was born in a quaint English town, Brackenridge, to parents who were both academics. His mother, an archaeologist,\nand his father, a historian, often took him on their research trips around the world. This exposure to different cultures sparked his\ncuriosity and adventurous spirit. He became an avid reader, especially of spy novels and adventure tales. As a child, Sebastian had a\nlove for puzzles, codes, and mysteries. He was part of a local chess club and also excelled in martial arts. Although he was naturally\ninclined towards academic pursuits like his parents, his heart always sought thrill and adventure.\n\nSebastian studied journalism and international relations in university and was recruited by the government's intelligence agency. He\nunderwent rigorous training in espionage, intelligence gathering, cryptography, and combat.\n\nSebastian adopted the alias of \"Ian Thorne\", a charismatic and well-traveled blogger. As Ian, he travels the world under the guise\nof documenting adventures through his blog, “The Wandering Quill”. This cover provides him ample opportunities to carry out his real job\n- gathering intelligence and performing covert operations for his agency. However - Sebastian tells almost no one that he’s a spy.\n\nHis interests are solving puzzles and riddles, martial arts, reading spy novels, trying street food in various countries, hiking and\nexploring historical ruins, and playing the violin, a skill he uses to blend in at high-profile events. He dislikes bureaucracy and\nred 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.\n\n```\n\n2. 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).\n\n3. Create embeddings based on content in the [companion name].md file - more on how to do this in [Generate embeddings](#4-generate-embeddings)\n\n4. Ask questions and have a conversation with your AI companion!\n\n\n## Adding\u002Fmodifying characters\n\nAll character data is stored in the `companions\u002F` directory. To add a companion,\nsimply add a description to the list in `companions.json`. You can control the model used\nin the \"llm\" section - use \"chatgpt\" for OpenAI or \"vicuna13b\" for Vicuna.\nPut image files in `public\u002F` in the root directory. Each character should have its own text file\nname `charactername.txt`. The format of the text file is as follows:\n\n```\nThe character's core description that is included with every prompt, and it should only\nbe a few sentences.\n\n###ENDPREAMBLE###\n\nHuman: Say something here\nCharacter name: Write a response in their voice\nHuman: Maybe another exchange\nCharacter:  More character dialog\n\n###ENDSEEDCHAT###\n\nParagraphs of character backstory.\n\nYou can add as many as you want - they'll be stored in the vectordb\n\n```\n\nThe **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.\n\n## Shortcomings\n\nOh, there are so many.\n\n- Currently the UI only shows the current chat and response, losing the history.\n- Vicuna has a cold start problem so can take a couple of minutes to get a response for the initial chat.\n- Error reporting is total crap. Particularly when deployed. So if you have a timeout, or other back end isue, it typically fails silently.\n- The Upstash message history is never cleared. To clear it, you have to go to Upstash and manually delete.\n\n## How to contribute to this repo\n\n### Code contribution workflow\n\nYou can fork this repo, make changes, and create a PR. Add **@ykhli or @timqian** as reviewers.\n\nIf you are new to contributing on github, here is a step-by-step guide:\n\n1. Click on `Fork` on the top right of this page\n2. 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:\n   \u003Cimg width=\"904\" alt=\"pr-preview\" src=\"https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fai-getting-started\u002Fassets\u002F3489963\u002F631e5f45-39ec-4b54-b9d1-b963e279dcc6\">\n\n3. Click on \"Contribute\" -> \"Open Pull Request\".\n4. Once you have a PR, you can add reviewers.\n\n### Other contributions\n\nFeel free to open feature requests, bug reports etc under Issues.\n\n## Python Support\n\n[appenz](https:\u002F\u002Fgithub.com\u002Fappenz) has contributed to a Python implementation for the companion app [here](https:\u002F\u002Fgithub.com\u002Fa16z-infra\u002Fcompanion-app\u002Ftree\u002Fpython-local\u002Fpython), 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.\n\n## Export to Character.ai\n\nIf 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.\n\nTo get started, run the following command:\n\n`\nnpm run export-to-character [COMPANION_NAME] [MODEL_NAME] [USER_ID]\n`\n\n- `COMPANION_NAME`: name of your companion. i.e Alice\n- `MODEL_NAME`: `chatgpt` or `vicuna13b`\n- `USER_ID`: you can find this on Clerk, under \"Users\" -> click on your user -> copy \"User ID\"\n\nOnce you run this script, you will see two files created under the root directory:\n\n- `[COMPANION_NAME]_chat_history.txt`: This outputs all of the chat history stored in Upstash\n- `[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.\n\n## Refs\n\n- https:\u002F\u002Fjs.langchain.com\u002Fdocs\u002Fmodules\u002Findexes\u002Fvector_stores\u002Fintegrations\u002Fpinecone\n- https:\u002F\u002Fjs.langchain.com\u002Fdocs\u002Fmodules\u002Fmodels\u002Fllms\u002Fintegrations#replicate\n- https:\u002F\u002Fjs.langchain.com\u002Fdocs\u002Fmodules\u002Fchains\u002Findex_related_chains\u002Fretrieval_qa\n","AI Companion App 是一个用于创建和托管具有记忆功能的AI伴侣的轻量级技术栈。该项目允许用户自定义AI伴侣的性格与背景故事，并通过向量数据库结合相似性搜索来增强对话深度，同时保持一定长度的对话历史以提供上下文感知能力。它基于TypeScript构建，支持ChatGPT和Vicuna模型，并可通过浏览器或短信进行交互。适用于开发浪漫关系、友谊建立、娱乐互动、个人辅导等多种场景下的虚拟助手。作为开发者教程和启动平台，适合对聊天机器人背后技术感兴趣的初学者参考学习。",2,"2026-06-11 03:37:28","high_star"]