Co-authored-by: Ethan Knox <norton120@gmail.com>
This commit is contained in:
7
.env.example
Normal file
7
.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
MEMGPT_SERVER_PASS=password
|
||||
MEMGPT_PG_DB=memgpt
|
||||
MEMGPT_PG_USER=memgpt
|
||||
MEMGPT_PG_PASSWORD=memgpt
|
||||
MEMGPT_PG_URL=memgpt
|
||||
MEMGPT_PG_HOST=memgpt_db
|
||||
OPENAI_API_KEY=sk-TheresAlwaysMoneyInTheBananaStand
|
||||
4
.github/workflows/black_format.yml
vendored
4
.github/workflows/black_format.yml
vendored
@@ -16,8 +16,8 @@ jobs:
|
||||
- name: "Setup Python, Poetry and Dependencies"
|
||||
uses: packetcoders/action-setup-cache-python-poetry@main
|
||||
with:
|
||||
python-version: "3.11"
|
||||
poetry-version: "1.7.1"
|
||||
python-version: "3.12"
|
||||
poetry-version: "1.8.2"
|
||||
install-args: "-E dev" # TODO: change this to --group dev when PR #842 lands
|
||||
|
||||
- name: Run Black
|
||||
|
||||
22
.github/workflows/tests.yml
vendored
22
.github/workflows/tests.yml
vendored
@@ -39,19 +39,19 @@ jobs:
|
||||
poetry run memgpt quickstart --backend memgpt
|
||||
fi
|
||||
|
||||
- name: Run docker compose server
|
||||
env:
|
||||
MEMGPT_PG_DB: memgpt
|
||||
MEMGPT_PG_USER: memgpt
|
||||
MEMGPT_PG_PASSWORD: memgpt
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
MEMGPT_CONFIG_PATH: configs/server_config.yaml
|
||||
#- name: Run docker compose server
|
||||
# env:
|
||||
# MEMGPT_PG_DB: memgpt
|
||||
# MEMGPT_PG_USER: memgpt
|
||||
# MEMGPT_PG_PASSWORD: memgpt
|
||||
# MEMGPT_SERVER_PASS: test_server_token
|
||||
# MEMGPT_CONFIG_PATH: configs/server_config.yaml
|
||||
|
||||
run: docker compose up -d
|
||||
# run: docker compose up -d
|
||||
|
||||
- name: Run server tests
|
||||
env:
|
||||
MEMGPT_PGURI: postgresql+pg8000://memgpt:memgpt@localhost:8888/memgpt
|
||||
MEMGPT_PG_PORT: 8888
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
run: |
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
|
||||
- name: Run tests with pytest
|
||||
env:
|
||||
MEMGPT_PGURI: postgresql+pg8000://memgpt:memgpt@localhost:8888/memgpt
|
||||
MEMGPT_PG_PORT: 8888
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
|
||||
- name: Run storage tests
|
||||
env:
|
||||
MEMGPT_PGURI: postgresql+pg8000://memgpt:memgpt@localhost:5432/memgpt
|
||||
MEMGPT_PG_PORT: 8888
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
run: |
|
||||
|
||||
24
.gitignore
vendored
24
.gitignore
vendored
@@ -387,18 +387,7 @@ __pycache__/
|
||||
.Python
|
||||
develop-eggs/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
eggs#memgpt/memgpt-server:0.3.7
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
@@ -1017,4 +1006,13 @@ FodyWeavers.xsd
|
||||
### VisualStudio Patch ###
|
||||
# Additional files built by Visual Studio
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim,linux,macos,pydev,python,eclipse,pycharm,windows,netbeans,pycharm+all,pycharm+iml,visualstudio,jupyternotebooks,visualstudiocode,xcode,xcodeinjection
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim,linux,macos,pydev,python,eclipse,pycharm,windows,netbeans,pycharm+all,pycharm+iml,visualstudio,jupyternotebooks,visualstudiocode,xcode,xcodeinjection
|
||||
|
||||
|
||||
## cached db data
|
||||
pgdata/
|
||||
!pgdata/.gitkeep
|
||||
|
||||
## pytest mirrors
|
||||
memgpt/.pytest_cache/
|
||||
memgpy/pytest.ini
|
||||
0
.persist/.gitkeep
Normal file
0
.persist/.gitkeep
Normal file
@@ -138,3 +138,10 @@ Please be sure to follow the project's Code of Conduct.
|
||||
Need help or just want to say hi? We're here for you. Reach out through filing an issue on this GitHub repository or message us on our [Discord server](https://discord.gg/9GEQrxmVyE).
|
||||
|
||||
Thanks for making MemGPT even more fantastic!
|
||||
|
||||
## WIP - 🐋 Docker Development
|
||||
If you prefer to keep your resources isolated by developing purely in containers, you can start MemGPT in development with:
|
||||
```shell
|
||||
docker compose -f compose.yaml -f development.compose.yml up
|
||||
```
|
||||
This will volume mount your local codebase and reload the server on file changes.
|
||||
35
Dockerfile
35
Dockerfile
@@ -1,6 +1,7 @@
|
||||
# The builder image, used to build the virtual environment
|
||||
FROM python:3.11-bookworm as builder
|
||||
|
||||
ARG MEMGPT_ENVIRONMENT=PRODUCTION
|
||||
ENV MEMGPT_ENVIRONMENT=${MEMGPT_ENVIRONMENT}
|
||||
RUN pip install poetry==1.4.2
|
||||
|
||||
ENV POETRY_NO_INTERACTION=1 \
|
||||
@@ -11,21 +12,41 @@ ENV POETRY_NO_INTERACTION=1 \
|
||||
WORKDIR /app
|
||||
|
||||
COPY pyproject.toml poetry.lock ./
|
||||
RUN poetry lock --no-update
|
||||
RUN if [ "$MEMGPT_ENVIRONMENT" = "DEVELOPMENT" ] ; then \
|
||||
poetry install --no-root -E "postgres server dev autogen" ; \
|
||||
else \
|
||||
poetry install --without dev --no-root -E "postgres server" && \
|
||||
rm -rf $POETRY_CACHE_DIR ; \
|
||||
fi
|
||||
|
||||
RUN poetry add psycopg2-binary
|
||||
|
||||
RUN poetry install --without dev --no-root -E "postgres server" && rm -rf $POETRY_CACHE_DIR
|
||||
|
||||
# The runtime image, used to just run the code provided its virtual environment
|
||||
FROM python:3.11-slim-bookworm as runtime
|
||||
|
||||
ARG MEMGPT_ENVIRONMENT=PRODUCTION
|
||||
ENV MEMGPT_ENVIRONMENT=${MEMGPT_ENVIRONMENT}
|
||||
ENV VIRTUAL_ENV=/app/.venv \
|
||||
PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
|
||||
|
||||
COPY memgpt ./memgpt
|
||||
COPY ./memgpt /memgpt
|
||||
|
||||
EXPOSE 8083
|
||||
|
||||
ENTRYPOINT ["python", "-m", "uvicorn", "memgpt.server.rest_api.server:app", "--host", "0.0.0.0", "--port", "8083"]
|
||||
CMD ./memgpt/server/startup.sh
|
||||
|
||||
# allow for in-container development and testing
|
||||
FROM builder as development
|
||||
ARG MEMGPT_ENVIRONMENT=PRODUCTION
|
||||
ENV MEMGPT_ENVIRONMENT=${MEMGPT_ENVIRONMENT}
|
||||
ENV VIRTUAL_ENV=/app/.venv \
|
||||
PATH="/app/.venv/bin:$PATH"
|
||||
ENV PYTHONPATH=/
|
||||
WORKDIR /
|
||||
COPY ./tests /tests
|
||||
COPY ./memgpt /memgpt
|
||||
COPY ./configs/server_config.yaml /root/.memgpt/config
|
||||
EXPOSE 8083
|
||||
|
||||
CMD ./memgpt/server/startup.sh
|
||||
|
||||
31
compose.yaml
31
compose.yaml
@@ -1,21 +1,30 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
pgvector_db:
|
||||
image: ankane/pgvector:latest
|
||||
memgpt_db:
|
||||
image: ankane/pgvector:v0.5.1
|
||||
networks:
|
||||
default:
|
||||
aliases:
|
||||
- pgvector_db
|
||||
- memgpt-db
|
||||
environment:
|
||||
- POSTGRES_USER=${MEMGPT_PG_USER}
|
||||
- POSTGRES_PASSWORD=${MEMGPT_PG_PASSWORD}
|
||||
- POSTGRES_DB=${MEMGPT_PG_DB}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
- ./.persist/pgdata:/var/lib/postgresql/data
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
memgpt_server:
|
||||
image: memgpt/memgpt-server:latest
|
||||
hostname: memgpt-server
|
||||
depends_on:
|
||||
- pgvector_db
|
||||
- memgpt_db
|
||||
ports:
|
||||
- "8083:8083"
|
||||
- "8283:8283"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- MEMGPT_PGURI=postgresql://${MEMGPT_PG_USER}:${MEMGPT_PG_PASSWORD}@pgvector_db:5432/${MEMGPT_PG_DB}
|
||||
- MEMGPT_SERVER_PASS=${MEMGPT_SERVER_PASS} # memgpt server password
|
||||
@@ -26,8 +35,10 @@ services:
|
||||
volumes:
|
||||
- ./configs/server_config.yaml:/root/.memgpt/config # config file
|
||||
- ~/.memgpt/credentials:/root/.memgpt/credentials # credentials file
|
||||
memgpt_nginx:
|
||||
hostname: memgpt-nginx
|
||||
image: nginx:stable-alpine3.17-slim
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
ports:
|
||||
- "8083:8083"
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
- "80:80"
|
||||
|
||||
@@ -12,27 +12,26 @@ context_window = 8192
|
||||
[embedding]
|
||||
embedding_endpoint_type = openai
|
||||
embedding_endpoint = https://api.openai.com/v1
|
||||
embedding_model = text-embedding-ada-002
|
||||
embedding_dim = 1536
|
||||
embedding_chunk_size = 300
|
||||
|
||||
[archival_storage]
|
||||
type = postgres
|
||||
path = /root/.memgpt/chroma
|
||||
uri = postgresql://memgpt:memgpt@pgvector_db:5432/memgpt
|
||||
uri = postgresql+pg8000://swis_memgpt:swis_memgpt@memgpt-db/swis_memgpt
|
||||
|
||||
[recall_storage]
|
||||
type = postgres
|
||||
path = /root/.memgpt
|
||||
uri = postgresql://memgpt:memgpt@pgvector_db:5432/memgpt
|
||||
uri = postgresql+pg8000://swis_memgpt:swis_memgpt@memgpt-db/swis_memgpt
|
||||
|
||||
[metadata_storage]
|
||||
type = postgres
|
||||
path = /root/.memgpt
|
||||
uri = postgresql://memgpt:memgpt@pgvector_db:5432/memgpt
|
||||
uri = postgresql+pg8000://swis_memgpt:swis_memgpt@memgpt-db/swis_memgpt
|
||||
|
||||
[version]
|
||||
memgpt_version = 0.3.7
|
||||
memgpt_version = 0.3.10
|
||||
|
||||
[client]
|
||||
anon_clientid = 00000000-0000-0000-0000-000000000000
|
||||
|
||||
28
development.compose.yml
Normal file
28
development.compose.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
services:
|
||||
memgpt_server:
|
||||
image: memgpt_server
|
||||
hostname: memgpt-server
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
target: development
|
||||
args:
|
||||
- MEMGPT_ENVIRONMENT=DEVELOPMENT
|
||||
depends_on:
|
||||
- memgpt_db
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- MEMGPT_SERVER_PASS=test_server_token
|
||||
volumes:
|
||||
- ./memgpt:/memgpt
|
||||
- ~/.memgpt/credentials:/root/.memgpt/credentials
|
||||
- ./configs/server_config.yaml:/root/.memgpt/config
|
||||
- ./CONTRIBUTING.md:/CONTRIBUTING.md
|
||||
- ./tests/pytest_cache:/memgpt/.pytest_cache
|
||||
- ./tests/pytest.ini:/memgpt/pytest.ini
|
||||
- ./pyproject.toml:/pyproject.toml
|
||||
- ./tests:/tests
|
||||
ports:
|
||||
- "8083:8083"
|
||||
- "8283:8283"
|
||||
@@ -17,6 +17,7 @@ import numpy as np
|
||||
from tqdm import tqdm
|
||||
import pandas as pd
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.config import MemGPTConfig
|
||||
from memgpt.agent_store.storage import StorageConnector, TableType
|
||||
from memgpt.config import MemGPTConfig
|
||||
@@ -428,15 +429,8 @@ class PostgresStorageConnector(SQLStorageConnector):
|
||||
self.db_model = get_db_model(config, self.table_name, table_type, user_id, agent_id)
|
||||
|
||||
# construct URI from enviornment variables
|
||||
if os.getenv("MEMGPT_PGURI"):
|
||||
self.uri = os.getenv("MEMGPT_PGURI")
|
||||
elif os.getenv("MEMGPT_PG_DB"):
|
||||
db = os.getenv("MEMGPT_PG_DB", "memgpt")
|
||||
user = os.getenv("MEMGPT_PG_USER", "memgpt")
|
||||
password = os.getenv("MEMGPT_PG_PASSWORD", "memgpt")
|
||||
port = os.getenv("MEMGPT_PG_PORT", "5432")
|
||||
url = os.getenv("MEMGPT_PG_URL", "localhost")
|
||||
self.uri = f"postgresql+pg8000://{user}:{password}@{url}:{port}/{db}"
|
||||
if settings.pg_uri:
|
||||
self.uri = settings.pg_uri
|
||||
else:
|
||||
# use config URI
|
||||
# TODO: remove this eventually (config should NOT contain URI)
|
||||
|
||||
@@ -6,6 +6,7 @@ import uuid
|
||||
import secrets
|
||||
from typing import Optional, List
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.constants import DEFAULT_HUMAN, DEFAULT_MEMGPT_MODEL, DEFAULT_PERSONA, DEFAULT_PRESET, LLM_MAX_TOKENS
|
||||
from memgpt.utils import enforce_types, printd
|
||||
from memgpt.data_types import AgentState, Source, User, LLMConfig, EmbeddingConfig, Token, Preset
|
||||
@@ -301,21 +302,14 @@ class PresetModel(Base):
|
||||
|
||||
|
||||
class MetadataStore:
|
||||
uri: Optional[str] = None
|
||||
|
||||
def __init__(self, config: MemGPTConfig):
|
||||
# TODO: get DB URI or path
|
||||
if config.metadata_storage_type == "postgres":
|
||||
# construct URI from enviornment variables
|
||||
if os.getenv("MEMGPT_PGURI"):
|
||||
self.uri = os.getenv("MEMGPT_PGURI")
|
||||
elif os.getenv("MEMGPT_PG_DB"):
|
||||
db = os.getenv("MEMGPT_PG_DB", "memgpt")
|
||||
user = os.getenv("MEMGPT_PG_USER", "memgpt")
|
||||
password = os.getenv("MEMGPT_PG_PASSWORD", "memgpt")
|
||||
port = os.getenv("MEMGPT_PG_PORT", "5432")
|
||||
url = os.getenv("MEMGPT_PG_URL", "localhost")
|
||||
self.uri = f"postgresql+pg8000://{user}:{password}@{url}:{port}/{db}"
|
||||
else:
|
||||
self.uri = config.metadata_storage_uri
|
||||
self.uri = settings.pg_uri if settings.pg_uri else config.metadata_storage_uri
|
||||
|
||||
elif config.metadata_storage_type == "sqlite":
|
||||
path = os.path.join(config.metadata_storage_path, "sqlite.db")
|
||||
self.uri = f"sqlite:///{path}"
|
||||
@@ -323,8 +317,7 @@ class MetadataStore:
|
||||
raise ValueError(f"Invalid metadata storage type: {config.metadata_storage_type}")
|
||||
|
||||
# Ensure valid URI
|
||||
if not self.uri:
|
||||
raise ValueError("Database URI is not provided or is invalid.")
|
||||
assert self.uri, "Database URI is not provided or is invalid."
|
||||
|
||||
# Check if tables need to be created
|
||||
self.engine = create_engine(self.uri)
|
||||
|
||||
0
memgpt/pytest.ini
Executable file
0
memgpt/pytest.ini
Executable file
@@ -9,6 +9,7 @@ from fastapi import FastAPI, HTTPException, Depends
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.server.rest_api.admin.users import setup_admin_router
|
||||
from memgpt.server.rest_api.agents.command import setup_agents_command_router
|
||||
from memgpt.server.rest_api.agents.config import setup_agents_config_router
|
||||
@@ -38,25 +39,17 @@ Start the server with:
|
||||
cd memgpt/server/rest_api
|
||||
poetry run uvicorn server:app --reload
|
||||
"""
|
||||
# override config with postgres enviornment (messy, but necessary for docker compose)
|
||||
# TODO: do something less gross
|
||||
if os.getenv("POSTGRES_URI"):
|
||||
config = MemGPTConfig.load()
|
||||
config.archival_storage_uri = os.getenv("POSTGRES_URI")
|
||||
config.recall_storage_uri = os.getenv("POSTGRES_URI")
|
||||
config.metadata_storage_uri = os.getenv("POSTGRES_URI")
|
||||
print(f"Overriding DB config URI with enviornment variable: {config.archival_storage_uri}")
|
||||
config.save()
|
||||
|
||||
config = MemGPTConfig.load()
|
||||
for memory_type in ("archival", "recall", "metadata"):
|
||||
setattr(config, f"{memory_type}_storage_uri", settings.pg_uri)
|
||||
config.save()
|
||||
|
||||
|
||||
interface: QueuingInterface = QueuingInterface()
|
||||
server: SyncServer = SyncServer(default_interface=interface)
|
||||
|
||||
|
||||
SERVER_PASS_VAR = "MEMGPT_SERVER_PASS"
|
||||
password = os.getenv(SERVER_PASS_VAR)
|
||||
|
||||
if password:
|
||||
if password := settings.server_pass:
|
||||
# if the pass was specified in the environment, use it
|
||||
print(f"Using existing admin server password from environment.")
|
||||
else:
|
||||
@@ -64,7 +57,6 @@ else:
|
||||
password = secrets.token_urlsafe(16)
|
||||
print(f"Generated admin server password for this session: {password}")
|
||||
|
||||
|
||||
security = HTTPBearer()
|
||||
|
||||
|
||||
@@ -78,20 +70,11 @@ ADMIN_PREFIX = "/admin"
|
||||
API_PREFIX = "/api"
|
||||
OPENAI_API_PREFIX = "/v1"
|
||||
|
||||
CORS_ORIGINS = [
|
||||
"http://localhost:4200",
|
||||
"http://localhost:4201",
|
||||
"http://localhost:8283",
|
||||
"http://127.0.0.1:4200",
|
||||
"http://127.0.0.1:4201",
|
||||
"http://127.0.0.1:8283",
|
||||
]
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=CORS_ORIGINS,
|
||||
allow_origins=settings.cors_origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
@@ -133,7 +116,7 @@ def on_startup():
|
||||
app.openapi_schema = app.openapi()
|
||||
|
||||
if app.openapi_schema:
|
||||
app.openapi_schema["servers"] = [{"url": "http://localhost:8283"}]
|
||||
app.openapi_schema["servers"] = [{"url": host} for host in settings.cors_origins]
|
||||
app.openapi_schema["info"]["title"] = "MemGPT API"
|
||||
|
||||
# Write out the OpenAPI schema to a file
|
||||
|
||||
7
memgpt/server/startup.sh
Executable file
7
memgpt/server/startup.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
echo "Starting MEMGPT server..."
|
||||
if [ "$MEMGPT_ENVIRONMENT" = "DEVELOPMENT" ] ; then
|
||||
uvicorn memgpt.server.rest_api.server:app --reload --reload-dir /memgpt --host 0.0.0.0 --port 8083
|
||||
else
|
||||
uvicorn memgpt.server.rest_api.server:app --host 0.0.0.0 --port 8083
|
||||
fi
|
||||
22
memgpt/settings.py
Normal file
22
memgpt/settings.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from typing import Optional
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_prefix="memgpt_")
|
||||
|
||||
server_pass: Optional[str] = None
|
||||
pg_db: Optional[str] = "memgpt"
|
||||
pg_user: Optional[str] = "memgpt"
|
||||
pg_password: Optional[str] = "memgpt"
|
||||
pg_host: Optional[str] = "localhost"
|
||||
pg_port: Optional[int] = 5432
|
||||
cors_origins: Optional[list] = ["http://memgpt.localhost", "http://localhost:8283", "http://localhost:8083"]
|
||||
|
||||
@property
|
||||
def pg_uri(self) -> str:
|
||||
return f"postgresql+pg8000://{self.pg_user}:{self.pg_password}@{self.pg_host}:{self.pg_port}/{self.pg_db}"
|
||||
|
||||
|
||||
# singleton
|
||||
settings = Settings()
|
||||
30
nginx.conf
Normal file
30
nginx.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
events {
|
||||
}
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 8083;
|
||||
listen [::]:8083;
|
||||
listen 8283;
|
||||
listen [::]:8283;
|
||||
server_name memgpt.localhost;
|
||||
set $api_target "http://memgpt-server:8083";
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
resolver 127.0.0.11; # docker dns
|
||||
proxy_pass $api_target;
|
||||
}
|
||||
}
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name not_found;
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
1711
poetry.lock
generated
1711
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,6 @@ questionary = "^2.0.1"
|
||||
pytz = "^2023.3.post1"
|
||||
tqdm = "^4.66.1"
|
||||
black = {extras = ["jupyter"], version = "^24.2.0"}
|
||||
pytest = { version = "^7.4.4", optional = true }
|
||||
setuptools = "^68.2.2"
|
||||
datasets = { version = "^2.14.6", optional = true}
|
||||
prettytable = "^3.9.0"
|
||||
@@ -40,7 +39,6 @@ chromadb = "^0.4.18"
|
||||
sqlalchemy-json = "^0.7.0"
|
||||
fastapi = {version = "^0.104.1", optional = true}
|
||||
uvicorn = {version = "^0.24.0.post1", optional = true}
|
||||
pytest-asyncio = {version = "^0.23.2", optional = true}
|
||||
pydantic = "^2.5.2"
|
||||
pyautogen = {version = "0.2.22", optional = true}
|
||||
html2text = "^2020.1.16"
|
||||
@@ -50,18 +48,21 @@ pexpect = {version = "^4.9.0", optional = true}
|
||||
pyright = {version = "^1.1.347", optional = true}
|
||||
python-box = "^7.1.1"
|
||||
sqlmodel = "^0.0.16"
|
||||
pytest-order = {version = "^1.2.0", optional = true}
|
||||
autoflake = {version = "^2.3.0", optional = true}
|
||||
llama-index = "^0.10.27"
|
||||
llama-index-embeddings-openai = "^0.1.1"
|
||||
llama-index-embeddings-huggingface = {version = "^0.2.0", optional = true}
|
||||
llama-index-embeddings-azure-openai = "^0.1.6"
|
||||
python-multipart = "^0.0.9"
|
||||
pytest-order = {version = "^1.2.0", optional = true}
|
||||
pytest-asyncio = {version = "^0.23.2", optional = true}
|
||||
pytest = { version = "^7.4.4", optional = true }
|
||||
pydantic-settings = "^2.2.1"
|
||||
httpx-sse = "^0.4.0"
|
||||
|
||||
[tool.poetry.extras]
|
||||
local = ["llama-index-embeddings-huggingface"]
|
||||
postgres = ["pgvector", "pg8000"]
|
||||
postgres = ["pgvector", "pg8000", "psycopg2-binary"]
|
||||
dev = ["pytest", "pytest-asyncio", "pexpect", "black", "pre-commit", "datasets", "pyright", "pytest-order", "autoflake"]
|
||||
server = ["websockets", "fastapi", "uvicorn"]
|
||||
autogen = ["pyautogen"]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export MEMGPT_VERSION=$(memgpt version)
|
||||
#docker build -t memgpt/memgpt-server:${MEMGPT_VERSION} --platform linux/x86_64 .
|
||||
docker buildx build --platform=linux/amd64,linux/arm64,linux/x86_64 -t memgpt/memgpt-server:${MEMGPT_VERSION} .
|
||||
docker buildx build --platform=linux/amd64,linux/arm64,linux/x86_64 --build-arg MEMGPT_ENVIRONMENT=RELEASE -t memgpt/memgpt-server:${MEMGPT_VERSION} .
|
||||
docker push memgpt/memgpt-server:${MEMGPT_VERSION}
|
||||
|
||||
6
tests/pytest.ini
Normal file
6
tests/pytest.ini
Normal file
@@ -0,0 +1,6 @@
|
||||
[pytest]
|
||||
pythonpath = /memgpt
|
||||
testpaths = /tests
|
||||
asyncio_mode = auto
|
||||
filterwarnings =
|
||||
ignore::pytest.PytestRemovedIn8Warning
|
||||
@@ -10,6 +10,7 @@ from dotenv import load_dotenv
|
||||
|
||||
from tests.config import TestMGPTConfig
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.server.rest_api.server import start_server
|
||||
from memgpt.credentials import MemGPTCredentials
|
||||
from memgpt.data_types import EmbeddingConfig, LLMConfig
|
||||
@@ -31,10 +32,7 @@ def run_server():
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Use os.getenv with a fallback to os.environ.get
|
||||
db_url = os.getenv("MEMGPT_PGURI") or os.environ.get("MEMGPT_PGURI")
|
||||
assert db_url, "Missing MEMGPT_PGURI"
|
||||
|
||||
db_url = settings.pg_db
|
||||
if os.getenv("OPENAI_API_KEY"):
|
||||
config = TestMGPTConfig(
|
||||
archival_storage_uri=db_url,
|
||||
|
||||
@@ -11,6 +11,7 @@ from dotenv import load_dotenv
|
||||
|
||||
from tests.config import TestMGPTConfig
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.credentials import MemGPTCredentials
|
||||
from memgpt.data_types import EmbeddingConfig, LLMConfig
|
||||
from .utils import wipe_config, wipe_memgpt_home
|
||||
@@ -43,8 +44,7 @@ def run_server():
|
||||
load_dotenv()
|
||||
|
||||
# Use os.getenv with a fallback to os.environ.get
|
||||
db_url = os.getenv("MEMGPT_PGURI") or os.environ.get("MEMGPT_PGURI")
|
||||
assert db_url, "Missing MEMGPT_PGURI"
|
||||
db_url = settings.pg_uri
|
||||
|
||||
if os.getenv("OPENAI_API_KEY"):
|
||||
config = TestMGPTConfig(
|
||||
@@ -130,11 +130,12 @@ def client(request):
|
||||
token = None
|
||||
|
||||
client = create_client(**request.param, token=token) # This yields control back to the test function
|
||||
yield client
|
||||
|
||||
# cleanup user
|
||||
if request.param["base_url"]:
|
||||
admin.delete_user(test_user_id) # Adjust as per your client's method
|
||||
try:
|
||||
yield client
|
||||
finally:
|
||||
# cleanup user
|
||||
if request.param["base_url"]:
|
||||
admin.delete_user(test_user_id) # Adjust as per your client's method
|
||||
|
||||
|
||||
# Fixture for test agent
|
||||
@@ -334,7 +335,6 @@ def test_presets(client, agent):
|
||||
# List all presets and make sure the preset is NOT in the list
|
||||
all_presets = client.list_presets()
|
||||
assert new_preset.id not in [p.id for p in all_presets], (new_preset, all_presets)
|
||||
|
||||
# Create a preset
|
||||
client.create_preset(preset=new_preset)
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
|
||||
# import memgpt
|
||||
from memgpt.settings import settings
|
||||
from memgpt.agent_store.storage import StorageConnector, TableType
|
||||
from memgpt.cli.cli_load import load_directory
|
||||
|
||||
# from memgpt.data_sources.connectors import DirectoryConnector, load_data
|
||||
from memgpt.settings import settings
|
||||
from memgpt.credentials import MemGPTCredentials
|
||||
from memgpt.metadata import MetadataStore
|
||||
from memgpt.data_types import User, AgentState, EmbeddingConfig, LLMConfig
|
||||
@@ -58,10 +60,7 @@ def test_load_directory(
|
||||
|
||||
# setup config
|
||||
if metadata_storage_connector == "postgres":
|
||||
if not os.getenv("MEMGPT_PGURI"):
|
||||
print("Skipping test, missing PG URI")
|
||||
return
|
||||
TEST_MEMGPT_CONFIG.metadata_storage_uri = os.getenv("MEMGPT_PGURI")
|
||||
TEST_MEMGPT_CONFIG.metadata_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.metadata_storage_type = "postgres"
|
||||
elif metadata_storage_connector == "sqlite":
|
||||
print("testing sqlite metadata")
|
||||
@@ -69,10 +68,7 @@ def test_load_directory(
|
||||
else:
|
||||
raise NotImplementedError(f"Storage type {metadata_storage_connector} not implemented")
|
||||
if passage_storage_connector == "postgres":
|
||||
if not os.getenv("MEMGPT_PGURI"):
|
||||
print("Skipping test, missing PG URI")
|
||||
return
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = os.getenv("MEMGPT_PGURI")
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.archival_storage_type = "postgres"
|
||||
elif passage_storage_connector == "chroma":
|
||||
print("testing chroma passage storage")
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
from memgpt.constants import DEFAULT_HUMAN, DEFAULT_PERSONA, DEFAULT_PRESET
|
||||
import pytest
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.agent import Agent, save_agent
|
||||
from memgpt.metadata import MetadataStore
|
||||
from memgpt.data_types import User, AgentState, Source, LLMConfig
|
||||
@@ -16,11 +17,8 @@ from memgpt.models.pydantic_models import HumanModel, PersonaModel
|
||||
@pytest.mark.parametrize("storage_connector", ["sqlite"])
|
||||
def test_storage(storage_connector):
|
||||
if storage_connector == "postgres":
|
||||
if not os.getenv("MEMGPT_PGURI"):
|
||||
print("Skipping test, missing PG URI")
|
||||
return
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = os.environ["MEMGPT_PGURI"]
|
||||
TEST_MEMGPT_CONFIG.recall_storage_uri = os.environ["MEMGPT_PGURI"]
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.recall_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.archival_storage_type = "postgres"
|
||||
TEST_MEMGPT_CONFIG.recall_storage_type = "postgres"
|
||||
if storage_connector == "sqlite":
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
from openai import OpenAI
|
||||
import uvicorn
|
||||
from openai import OpenAI, APIConnectionError
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
def test_openai_assistant():
|
||||
client = OpenAI(base_url="http://127.0.0.1:8080/v1")
|
||||
|
||||
# create assistant
|
||||
assistant = client.beta.assistants.create(
|
||||
name="Math Tutor",
|
||||
instructions="You are a personal math tutor. Write and run code to answer math questions.",
|
||||
# tools=[{"type": "code_interpreter"}],
|
||||
model="gpt-4-turbo-preview",
|
||||
)
|
||||
|
||||
try:
|
||||
assistant = client.beta.assistants.create(
|
||||
name="Math Tutor",
|
||||
instructions="You are a personal math tutor. Write and run code to answer math questions.",
|
||||
# tools=[{"type": "code_interpreter"}],
|
||||
model="gpt-4-turbo-preview",
|
||||
)
|
||||
except APIConnectionError as e:
|
||||
logger.error("Connection issue with localhost openai stub: %s", e)
|
||||
return
|
||||
# create thread
|
||||
thread = client.beta.threads.create()
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from dotenv import load_dotenv
|
||||
from tests.config import TestMGPTConfig
|
||||
|
||||
utils.DEBUG = True
|
||||
from memgpt.settings import settings
|
||||
from memgpt.credentials import MemGPTCredentials
|
||||
from memgpt.server.server import SyncServer
|
||||
from memgpt.data_types import EmbeddingConfig, LLMConfig
|
||||
@@ -19,9 +20,7 @@ def server():
|
||||
wipe_config()
|
||||
wipe_memgpt_home()
|
||||
|
||||
# Use os.getenv with a fallback to os.environ.get
|
||||
db_url = os.getenv("MEMGPT_PGURI") or os.environ.get("MEMGPT_PGURI")
|
||||
assert db_url, "Missing MEMGPT_PGURI"
|
||||
db_url = settings.pg_db
|
||||
|
||||
if os.getenv("OPENAI_API_KEY"):
|
||||
config = TestMGPTConfig(
|
||||
@@ -180,7 +179,7 @@ def test_user_message(server, user_id, agent_id):
|
||||
server.user_message(user_id=user_id, agent_id=agent_id, message="Hello?")
|
||||
|
||||
|
||||
@pytest.mark.order5
|
||||
@pytest.mark.order(5)
|
||||
def test_get_recall_memory(server, user_id, agent_id):
|
||||
# test recall memory cursor pagination
|
||||
cursor1, messages_1 = server.get_agent_recall_cursor(user_id=user_id, agent_id=agent_id, reverse=True, limit=2)
|
||||
@@ -207,7 +206,7 @@ def test_get_recall_memory(server, user_id, agent_id):
|
||||
messages_1 = server.get_agent_messages(user_id=user_id, agent_id=agent_id, start=0, count=1)
|
||||
assert len(messages_1) == 1
|
||||
messages_2 = server.get_agent_messages(user_id=user_id, agent_id=agent_id, start=1, count=1000)
|
||||
messages_3 = server.get_agent_messages(user_id=user_id, agent_id=agent_id, start=1, count=5)
|
||||
messages_3 = server.get_agent_messages(user_id=user_id, agent_id=agent_id, start=1, count=2)
|
||||
# not sure exactly how many messages there should be
|
||||
assert len(messages_2) > len(messages_3)
|
||||
# test safe empty return
|
||||
@@ -215,7 +214,7 @@ def test_get_recall_memory(server, user_id, agent_id):
|
||||
assert len(messages_none) == 0
|
||||
|
||||
|
||||
@pytest.mark.order6
|
||||
@pytest.mark.order(6)
|
||||
def test_get_archival_memory(server, user_id, agent_id):
|
||||
# test archival memory cursor pagination
|
||||
cursor1, passages_1 = server.get_agent_archival_cursor(user_id=user_id, agent_id=agent_id, reverse=False, limit=2, order_by="text")
|
||||
|
||||
@@ -3,6 +3,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
||||
import uuid
|
||||
import pytest
|
||||
|
||||
from memgpt.settings import settings
|
||||
from memgpt.agent_store.storage import StorageConnector, TableType
|
||||
from memgpt.embeddings import embedding_model, query_embedding
|
||||
from memgpt.data_types import Message, Passage, EmbeddingConfig, AgentState, LLMConfig
|
||||
@@ -132,11 +133,8 @@ def test_storage(
|
||||
model="gpt-4",
|
||||
)
|
||||
if storage_connector == "postgres":
|
||||
if not os.getenv("MEMGPT_PGURI"):
|
||||
print("Skipping test, missing PG URI")
|
||||
return
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = os.environ["MEMGPT_PGURI"]
|
||||
TEST_MEMGPT_CONFIG.recall_storage_uri = os.environ["MEMGPT_PGURI"]
|
||||
TEST_MEMGPT_CONFIG.archival_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.recall_storage_uri = settings.pg_uri
|
||||
TEST_MEMGPT_CONFIG.archival_storage_type = "postgres"
|
||||
TEST_MEMGPT_CONFIG.recall_storage_type = "postgres"
|
||||
if storage_connector == "lancedb":
|
||||
|
||||
Reference in New Issue
Block a user