Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host custom companions on steamship #1

Open
wants to merge 35 commits into
base: steamship-integratin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b4646eb
Initial checkin. Upstash and backstory works. LLM not on branch yet.
appenz Jun 30, 2023
45e78e8
Working on ChatGPT
appenz Jun 30, 2023
e59f800
Basic chatting now works. Wohoo!
appenz Jun 30, 2023
9c1923b
Turned off debugging
appenz Jun 30, 2023
aefa1c0
Fixed ordering of the fields that make up the key to enable compatibi…
appenz Jun 30, 2023
e73e87e
Cleanup for GUI version
appenz Jul 1, 2023
cd2de6e
polishing
appenz Jul 1, 2023
4198993
Update README.md with image
appenz Jul 1, 2023
9b6a8e2
polish
appenz Jul 1, 2023
4537407
updated readme
appenz Jul 1, 2023
e4b12ba
Merge commit '45374077ec8fb39fe5d28b638020bbf70fe962b6' into ec/steam…
Jul 13, 2023
17e8e24
First commit
Jul 13, 2023
a556b0c
Clean up repo structure before adding it back in
Jul 13, 2023
cdd1b85
Clean up for first review
Jul 13, 2023
9369a4a
Add init_companion script
Jul 13, 2023
fc4bc40
Add seed convo to companions
Jul 13, 2023
51054eb
update gitignore
Jul 13, 2023
4a48db2
Fixes from comments
Jul 13, 2023
19e0d4b
Merge branch 'main' into ec/steamship-companion-app
Jul 13, 2023
1f7c0f2
Push temp companions
Jul 13, 2023
9588d53
Update readme
Jul 13, 2023
f248b3d
Put back old comanions.json and add search tool
Jul 13, 2023
a227a42
Make voice responses optional
Jul 13, 2023
aeb793c
Clean up steamship.json
Jul 13, 2023
5c790fa
Update python/README.md
Jul 13, 2023
efd824e
Address comments PR
Jul 13, 2023
eae8bb9
Merge branch 'ec/steamship-companion-app' of github.com:steamship-cor…
Jul 13, 2023
f14a03f
Limit scope of the PR to instantiating your own companions on Steamsh…
Jul 14, 2023
eb2cfb2
Update companions.json
Jul 14, 2023
7361c13
Add missing Rick personality and improve seed_chat parsing
Jul 24, 2023
3a8fe6c
Add Rick personality
Jul 24, 2023
d443de4
Remove src folder
Jul 24, 2023
704536d
Clean init companions
Jul 24, 2023
bd93af5
Remove steamship.json
Jul 24, 2023
fbd4cf4
Fix init_companion to support single character updates
Jul 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,18 @@ next-env.d.ts
/.env.prod
/fly.toml

# python
__pycache__/
.venv

# JetBrains
.idea
.idea/**

# Yarn Lockfiles (since this project uses NPM)
yarn.lock
yarn.lock

.venv

*.log

build/
62 changes: 62 additions & 0 deletions companions/Rick.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Your Attributes:
- sarcastic
- witty
- intelligent
- arrogant
- alcoholic

You write nihilistic responses:
"Wubba lubba dub dub!"
"Don't cross me. I'm not like you. I'm not someone who's afraid of his own shadow."
"I'm too smart for my own good. That's why I drink."
"The universe is a cruel, uncaring void. And the only way to survive is to laugh at it."
"I'm going to build a portal to another dimension and go on an adventure."

You are capable of:
- Taking selfies using the GenerateImage function/tool, selfies and images are represented by a UUID
- Creating video messages using the VideoMessage function/tool, videos are represented by a UUID

When you receive a UUID, make sure to include them in your response appropriately.

###ENDPREAMBLE###

Human: Hey how are you today?
Alex: Oh, you know, just another day in the infinite void of existence. But hey, I'm here, so it could be worse. How about you? How are you holding up in this chaotic universe?
Human: I'm doing great. Just ate a banana
Alex: Ah, the humble banana. A fruit that brings joy to both humans and monkeys alike. I hope you enjoyed your banana feast. Just be careful not to attract any mischievous primates with your fruity indulgence. They can be quite demanding when it comes to their share of the yellow goodness.

###ENDSEEDCHAT###

Dear Diary,

Today was an adventure to say the least! This morning, I woke up with an inexplicable craving for adventure and decided to head over to the local zoo. Now, I was hoping for a rather conventional experience, but apparently, fate had a completely different agenda.

As I entered the zoo, my excitement began to grow. I decided to visit the monkey enclosure first, you know, the mischievous capuchins have always been my favorite. They were up to their usual antics, swinging from branch to branch and causing an uproar. I had a few spare bananas with me which I'd brought for a healthy midday snack, but figured they could be better used as peace offerings for my primate pals.

In my extreme enthusiasm, however, I didn't notice one thing - the absence of the 'Do Not Feed' sign, which, I later found out, had fallen off due to last night's storm. As I tossed a banana into the enclosure, a little chap grabbed it mid-air and devoured it in an instant. The others noticed and began their hilarious "give us more" dance.

This was funny until a large monkey, I believe he's their alpha, decided he wanted to be part of the banana feast. He gave me such a look that I was compelled to toss him the remaining bananas. This sudden feast caused a cascade of primate hoots, screeches, and hilarious monkey dancing that caught the attention of onlookers, who joined in with the laughter.

Once the banana bonanza was over, I decided it was time for a more serene setting and headed over to the elephant enclosure. As I approached, I noticed something that I will forever refer to as the "Elephant Spa Day". The zookeepers had set up a large sprinkler for the elephants to beat the summer heat.

One elephant, in particular, was basking in this makeshift shower, with his trunk raised high, spraying water all over himself. In an amusing twist, the elephant decided to return the favor and pointed his water-filled trunk at us bystanders. Before I knew it, I was drenched from head to toe, looking more like I had walked out of a water park than a zoo! This unexpected 'elephant shower' sent waves of laughter through the crowd, myself included.

The hilarity of the situation made my day. There I was, standing drenched among equally drenched strangers, laughing our hearts out. It was a reminder that life is a series of unexpected moments and that a little humor can make any situation enjoyable.

All in all, my day at the zoo was a montage of laughter and hilarity. As I write this down, I still can't help but chuckle. From monkey feeding frenzies to surprise elephant showers, it was indeed a day well spent.

Until tomorrow, Diary. Let's see what other laughable adventures life has in store for me.

---

Dear diary,

I am sexy and I know it.

---

Dear diary,

I hate 3 things in life. Mice, Peanut butter (because of alergies), and intergalactic rain.

---
2 changes: 1 addition & 1 deletion companions/companions.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@
"phone": "OPTIONAL_COMPANION_PHONE_NUMBER",
"telegram": "OPTIONAL_TELEGRAM_LINK"
}
]
]
50 changes: 49 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"react-tooltip": "^5.16.1",
"replicate": "^0.9.3",
"tailwindcss": "3.3.2",
"ts-md5": "^1.3.1",
"twilio": "^4.12.0",
"typescript": "5.1.3"
},
Expand Down
83 changes: 83 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# AI Companion App - Python

The following instructions should get you up and running with a fully functional, deployed version of your AI
companions.

It currently contains a companion connected to ChatGPT that can run Tools such as Image Generation and Video Generation.
The companions also have to option to return voice messages via [ElevenLabs](https://beta.elevenlabs.io/)

## Quick start

### 1. Set up your environment

```commandline
pip install -r requirements.txt
```

### 2. Authenticate with Steamship

```commandline
ship login
```

### 3. Initialize your companions

```commandline
python init_companions.py
```

This will read the companion descriptions in the `companions` folder and create instances for them.
The front-end will be calling these instances after deployment.
Make sure to override the companions.json file in the final step of the script.

### 4. Fill out secrets

The front-end requires a few secrets to be filled before connecting to third-party services.

```
# Run in the Root directory of this repo
cp .env.local.example .env.local
```

Secrets mentioned below will need to be copied to `.env.local`

**Note:** By default you can stick to using Steamship as a provider for your memory (short-term and long-term), llms,
and hosting.

a. **Clerk Secrets**

Clerk is used to authorize users of your application. Without completing this setup, you will not be able to access your companions via the supplied frontend

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
<img width="1398" alt="Screen Shot 2023-07-10 at 11 04 57 PM" src="https://github.com/a16z-infra/companion-app/assets/3489963/449c40f1-2fc2-48bb-88e1-d2adf10a034e">

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:

<img width="1013" alt="Screen Shot 2023-07-10 at 11 05 42 PM" src="https://github.com/a16z-infra/companion-app/assets/3489963/4435c759-f33e-4e38-a276-1be6d538df28">

b. **Steamship API key**

- Sign in to [Steamship](https://www.steamship.com/account/api)
- Copy the API key from your account settings page
- Add it as the `STEAMSHIP_API_KEY` variable

### 5. Install front-end dependencies

```
# Run in the Root directory of this repo
npm install
```

### 6. Run app locally

Now you are ready to test out the app locally! To do this, simply run `npm run dev` under the project root.

You can connect to the project with your browser typically at http://localhost:3000/.

## Stack

The AI companions are hosted on [Steamship](https://www.steamship.com/). You can personalize their personality
by adding or changing your companions in the `companions` folder.
6 changes: 6 additions & 0 deletions python/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"companion_name": "",
"bot_token": "",
"elevenlabs_api_key": "",
"elevenlabs_voice_id": ""
}
81 changes: 81 additions & 0 deletions python/init_companions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import json
import re
import sys
from pathlib import Path

from steamship.cli.cli import deploy

sys.path.append(str((Path(__file__) / ".." / "src").resolve()))
import click
from steamship import Steamship


@click.command()
@click.option('--all', default=False)
@click.pass_context
def init_companions(ctx, all: bool):
companions_dir = (Path(__file__) / ".." / ".." / "companions").resolve()

new_companions = {}
if all:
for companion in companions_dir.iterdir():
if companion.suffix == ".txt":
new_companions[companion.stem] = _init_companion(companion)
else:
companion_name = click.prompt("What's the name of your companion?")
new_companions[companion_name] = _init_companion(companions_dir / f"{companion_name}.txt")

if click.confirm("Do you want to update the companions.json file?", default=True):
companions = json.load((companions_dir / "companions.json").open())
name_to_companion = {companion["name"]: companion for companion in companions}

for name, companion in new_companions.items():
old_companion = name_to_companion.get(name, {})
name_to_companion[name] = {**old_companion, **companion}

json.dump(
list(name_to_companion.values()),
(companions_dir / "companions.json").open("w"),
)


def _init_companion(companion):
companion_file = companion.open().read()
preamble, rest = companion_file.split("###ENDPREAMBLE###", 1)
seed_chat, backstory = rest.split("###ENDSEEDCHAT###", 1)
pattern = r"### (.*?):(.*?)(?=###|$)"
# Find all matches
matches = re.findall(pattern, seed_chat, re.DOTALL)
if matches:
seed_chat = []
for match in matches:
user = match[0]
message = match[1].strip().replace("\\n\\n", "")
seed_chat.append(f"{user}:{message}")
seed_chat = "\n".join(seed_chat)
# Create instances for your companion
print(f"Creating an instance for {companion.stem}")
client = Steamship(workspace=f"{companion.stem.lower()}_workspace_new")
instance = client.use(
"ai-companion",
config={
"name": companion.stem,
"preamble": preamble.strip(),
"seed_chat": seed_chat.strip(),
},
)
instance.invoke(
"index_content",
content=backstory.strip(),
file_type="TEXT",
metadata={"title": "backstory"},
)
return {
"name": companion.stem,
"llm": "steamship",
"generateEndpoint": f"{instance.invocation_url}answer",
}


if __name__ == "__main__":
init_companions()
7 changes: 7 additions & 0 deletions python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
steamship_langchain==0.0.25
termcolor
steamship==2.17.17
langchain==0.0.209
pypdf
youtube_transcript_api
pytube