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

Revert main #120

Merged
merged 6 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
66 changes: 18 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,10 @@ Memory-GPT (or MemGPT in short) is a system that intelligently manages different

## Running MemGPT locally

Install MemGPT:
Install dependencies:

```sh
pip install pymemgpt
```

To update the package, run
```sh
pip install pymemgpt -U
pip install -r requirements.txt
```

Add your OpenAI API key to your environment:
Expand All @@ -94,37 +89,12 @@ export OPENAI_API_KEY=YOUR_API_KEY
set OPENAI_API_KEY=YOUR_API_KEY
```

To run MemGPT for as a conversation agent in CLI mode, simply run `memgpt`:
To run MemGPT for as a conversation agent in CLI mode, simply run `main.py`:

```sh
memgpt
python3 main.py
```

<details>
<summary><strong>Debugging command not found</strong></summary>

If you get `command not found` (Linux/MacOS), or a `CommandNotFoundException` (Windows), the directory where pip installs scripts is not in your PATH. You can either add that directory to your path (`pip show pip | grep Scripts`) or instead just run:
```sh
python -m memgpt
```
</details>

<details>
<summary><strong>Building from source</strong></summary>

Clone this repo: `git clone https://github.com/cpacker/MemGPT.git`

Using poetry:
1. Install poetry: `pip install poetry`
2. Run `poetry install`
3. Run `poetry run memgpt`

Using pip:
1. Run `pip install -e .`
2. Run `python3 main.py`
</details>


If you're using Azure OpenAI, set these variables instead:

```sh
Expand All @@ -135,31 +105,31 @@ export AZURE_OPENAI_VERSION = ...
export AZURE_OPENAI_DEPLOYMENT = ...

# then use the --use_azure_openai flag
memgpt --use_azure_openai
python main.py --use_azure_openai
```

To create a new starter user or starter persona (that MemGPT gets initialized with), create a new `.txt` file in `~/.memgpt/humans` or `~/.memgpt/personas`, then use the `--persona` or `--human` flag when running `main.py`. For example:
To create a new starter user or starter persona (that MemGPT gets initialized with), create a new `.txt` file in [/memgpt/humans/examples](/memgpt/humans/examples) or [/memgpt/personas/examples](/memgpt/personas/examples), then use the `--persona` or `--human` flag when running `main.py`. For example:

```sh
# assuming you created a new file ~/.memgpt/humans/me.txt
memgpt
# assuming you created a new file /memgpt/humans/examples/me.txt
python main.py
# Select me.txt during configuration process
```
-- OR --
```sh
# assuming you created a new file ~/.memgpt/humans/me.txt
memgpt --human me.txt
# assuming you created a new file /memgpt/humans/examples/me.txt
python main.py --human me.txt
```
You can also specify any of the starter users in [/memgpt/humans/examples](/memgpt/humans/examples) or any of the starter personas in [/memgpt/personas/examples](/memgpt/personas/examples).

### GPT-3.5 support
You can run MemGPT with GPT-3.5 as the LLM instead of GPT-4:
```sh
memgpt
python main.py
# Select gpt-3.5 during configuration process
```
-- OR --
```sh
memgpt --model gpt-3.5-turbo
python main.py --model gpt-3.5-turbo
```

**Note that this is experimental gpt-3.5-turbo support. It's quite buggy compared to gpt-4, but it should be runnable.**
Expand Down Expand Up @@ -240,7 +210,7 @@ id | name | age
To talk to this database, run:

```sh
memgpt --archival_storage_sqldb=memgpt/personas/examples/sqldb/test.db
python main.py --archival_storage_sqldb=memgpt/personas/examples/sqldb/test.db
```

And then you can input the path to your database, and your query.
Expand All @@ -263,15 +233,15 @@ To run our example where you can search over the SEC 10-K filings of Uber, Lyft,

2. In the root `MemGPT` directory, run
```bash
memgpt --archival_storage_files="memgpt/personas/examples/preload_archival/*.txt" --persona=memgpt_doc --human=basic
python3 main.py --archival_storage_files="memgpt/personas/examples/preload_archival/*.txt" --persona=memgpt_doc --human=basic
```

If you would like to load your own local files into MemGPT's archival memory, run the command above but replace `--archival_storage_files="memgpt/personas/examples/preload_archival/*.txt"` with your own file glob expression (enclosed in quotes).

#### Enhance with embeddings search
In the root `MemGPT` directory, run
```bash
memgpt main.py --archival_storage_files_compute_embeddings="<GLOB_PATTERN>" --persona=memgpt_doc --human=basic
python3 main.py --archival_storage_files_compute_embeddings="<GLOB_PATTERN>" --persona=memgpt_doc --human=basic
```

This will generate embeddings, stick them into a FAISS index, and write the index to a directory, and then output:
Expand All @@ -282,7 +252,7 @@ This will generate embeddings, stick them into a FAISS index, and write the inde

If you want to reuse these embeddings, run
```bash
memgpt --archival_storage_faiss_path="<DIRECTORY_WITH_EMBEDDINGS>" --persona=memgpt_doc --human=basic
python3 main.py --archival_storage_faiss_path="<DIRECTORY_WITH_EMBEDDINGS>" --persona=memgpt_doc --human=basic
```


Expand Down Expand Up @@ -314,7 +284,7 @@ MemGPT also enables you to chat with docs -- try running this example to talk to

3. In the root `MemGPT` directory, run
```bash
memgpt --archival_storage_faiss_path=<ARCHIVAL_STORAGE_FAISS_PATH> --persona=memgpt_doc --human=basic
python3 main.py --archival_storage_faiss_path=<ARCHIVAL_STORAGE_FAISS_PATH> --persona=memgpt_doc --human=basic
```
where `ARCHIVAL_STORAGE_FAISS_PATH` is the directory where `all_docs.jsonl` and `all_docs.index` are located.
If you downloaded from Hugging Face, it will be `memgpt/personas/docqa/llamaindex-api-docs`.
Expand Down
14 changes: 8 additions & 6 deletions memgpt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import memgpt.interface as interface
from memgpt.personas.personas import get_persona_text
from memgpt.humans.humans import get_human_text
from memgpt.constants import MEMGPT_DIR

model_choices = [
questionary.Choice("gpt-4"),
Expand All @@ -22,15 +23,14 @@
value="gpt-3.5-turbo",
),
]
memgpt_dir = os.path.join(os.path.expanduser("~"), ".memgpt")


class Config:
personas_dir = os.path.join("memgpt", "personas", "examples")
custom_personas_dir = os.path.join(memgpt_dir, "personas")
custom_personas_dir = os.path.join(MEMGPT_DIR, "personas")
humans_dir = os.path.join("memgpt", "humans", "examples")
custom_humans_dir = os.path.join(memgpt_dir, "humans")
configs_dir = os.path.join(memgpt_dir, "configs")
custom_humans_dir = os.path.join(MEMGPT_DIR, "humans")
configs_dir = os.path.join(MEMGPT_DIR, "configs")

def __init__(self):
os.makedirs(Config.custom_personas_dir, exist_ok=True)
Expand Down Expand Up @@ -247,7 +247,8 @@ def get_memgpt_personas():
+ Config.get_persona_choices(
[p for p in custom_personas_in_examples + default_personas],
get_persona_text,
Config.personas_dir,
None,
# Config.personas_dir,
)
+ [
questionary.Separator(),
Expand All @@ -274,7 +275,8 @@ def get_user_personas():
+ Config.get_persona_choices(
[p for p in custom_personas_in_examples + default_personas],
get_human_text,
Config.humans_dir,
None,
# Config.humans_dir,
)
+ [
questionary.Separator(),
Expand Down
20 changes: 14 additions & 6 deletions memgpt/constants.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
DEFAULT_MEMGPT_MODEL = 'gpt-4'
import os

MEMGPT_DIR = os.path.join(os.path.expanduser("~"), ".memgpt")

DEFAULT_MEMGPT_MODEL = "gpt-4"

FIRST_MESSAGE_ATTEMPTS = 10

INITIAL_BOOT_MESSAGE = "Boot sequence complete. Persona activated."
INITIAL_BOOT_MESSAGE_SEND_MESSAGE_THOUGHT = "Bootup sequence complete. Persona activated. Testing messaging functionality."
INITIAL_BOOT_MESSAGE_SEND_MESSAGE_THOUGHT = (
"Bootup sequence complete. Persona activated. Testing messaging functionality."
)
STARTUP_QUOTES = [
"I think, therefore I am.",
"All those moments will be lost in time, like tears in rain.",
Expand All @@ -12,7 +18,7 @@
INITIAL_BOOT_MESSAGE_SEND_MESSAGE_FIRST_MSG = STARTUP_QUOTES[2]

# Constants to do with summarization / conversation length window
MESSAGE_SUMMARY_WARNING_TOKENS = 7000 # the number of tokens consumed in a call before a system warning goes to the agent
MESSAGE_SUMMARY_WARNING_TOKENS = 7000 # the number of tokens consumed in a call before a system warning goes to the agent
MESSAGE_SUMMARY_WARNING_STR = f"Warning: the conversation history will soon reach its maximum length and be trimmed. Make sure to save any important information from the conversation to your memory before it is removed."

# Default memory limits
Expand All @@ -21,11 +27,13 @@

MAX_PAUSE_HEARTBEATS = 360 # in min

MESSAGE_CHATGPT_FUNCTION_MODEL = 'gpt-3.5-turbo'
MESSAGE_CHATGPT_FUNCTION_SYSTEM_MESSAGE = 'You are a helpful assistant. Keep your responses short and concise.'
MESSAGE_CHATGPT_FUNCTION_MODEL = "gpt-3.5-turbo"
MESSAGE_CHATGPT_FUNCTION_SYSTEM_MESSAGE = (
"You are a helpful assistant. Keep your responses short and concise."
)

#### Functions related

REQ_HEARTBEAT_MESSAGE = "request_heartbeat == true"
FUNC_FAILED_HEARTBEAT_MESSAGE = "Function call failed"
FUNCTION_PARAM_DESCRIPTION_REQ_HEARTBEAT = "Request an immediate heartbeat after function execution. Set to 'true' if you want to send a follow-up message or run a follow-up function."
FUNCTION_PARAM_DESCRIPTION_REQ_HEARTBEAT = "Request an immediate heartbeat after function execution. Set to 'true' if you want to send a follow-up message or run a follow-up function."
14 changes: 7 additions & 7 deletions memgpt/local_llm/chat_completion_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import json

from .webui.api import get_webui_completion
from .llm_chat_completion_wrappers import airoboros, dolphin
from .llm_chat_completion_wrappers import airoboros
from .utils import DotDict

HOST = os.getenv("OPENAI_API_BASE")
Expand All @@ -23,14 +23,14 @@ async def get_chat_completion(
if function_call != "auto":
raise ValueError(f"function_call == {function_call} not supported (auto only)")

if model == "airoboros-l2-70b-2.1":
llm_wrapper = airoboros.Airoboros21InnerMonologueWrapper()
elif model == "dolphin-2.1-mistral-7b":
llm_wrapper = dolphin.Dolphin21MistralWrapper()
if model == "airoboros_v2.1":
llm_wrapper = airoboros.Airoboros21Wrapper()
else:
# Warn the user that we're using the fallback
print(f"Warning: no wrapper specified for local LLM, using the default wrapper")
llm_wrapper = DEFAULT_WRAPPER
print(
f"Warning: could not find an LLM wrapper for {model}, using the airoboros wrapper"
)
llm_wrapper = airoboros.Airoboros21Wrapper()

# First step: turn the message sequence into a prompt that the model expects
prompt = llm_wrapper.chat_completion_to_prompt(messages, functions)
Expand Down
1 change: 1 addition & 0 deletions memgpt/local_llm/llm_chat_completion_wrappers/dolphin.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ def create_function_call(function_call):
if self.include_opening_brance_in_prefix:
prompt += "\n{"

print(prompt)
return prompt

def clean_function_args(self, function_name, function_args):
Expand Down
9 changes: 6 additions & 3 deletions memgpt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
InMemoryStateManagerWithFaiss,
)

from memgpt.config import Config, memgpt_dir
from memgpt.config import Config
from memgpt.constants import MEMGPT_DIR
import asyncio

app = typer.Typer()
Expand All @@ -43,7 +44,7 @@ def clear_line():
def save(memgpt_agent, cfg):
filename = utils.get_local_time().replace(" ", "_").replace(":", "_")
filename = f"{filename}.json"
directory = os.path.join(memgpt_dir, "saved_state")
directory = os.path.join(MEMGPT_DIR, "saved_state")
filename = os.path.join(directory, filename)
try:
if not os.path.exists(directory):
Expand Down Expand Up @@ -394,6 +395,8 @@ async def main(
).ask_async()
clear_line()

user_input = user_input.rstrip()

if user_input.startswith("!"):
print(f"Commands for CLI begin with '/' not '!'")
continue
Expand All @@ -416,7 +419,7 @@ async def main(
utils.get_local_time().replace(" ", "_").replace(":", "_")
)
filename = f"{filename}.pkl"
directory = os.path.join(memgpt_dir, "saved_chats")
directory = os.path.join(MEMGPT_DIR, "saved_chats")
try:
if not os.path.exists(directory):
os.makedirs(directory)
Expand Down
Loading