Skip to content

Commit

Permalink
Merge pull request #120 from cpacker/revert-main
Browse files Browse the repository at this point in the history
Revert main
  • Loading branch information
cpacker authored Oct 25, 2023
2 parents c9a1156 + 5c222a7 commit 35cbd5c
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 125 deletions.
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

0 comments on commit 35cbd5c

Please sign in to comment.