mirror of
https://github.com/cpacker/MemGPT.git
synced 2025-06-03 04:30:22 +00:00
feat: add workflow to build + test docker container (#1278)
This commit is contained in:
parent
4ddd0d4939
commit
048e55fe15
64
.github/workflows/docker-integration-tests.yaml
vendored
Normal file
64
.github/workflows/docker-integration-tests.yaml
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Set permissions for log directory
|
||||
run: |
|
||||
mkdir -p /home/runner/.memgpt/logs
|
||||
sudo chown -R $USER:$USER /home/runner/.memgpt/logs
|
||||
chmod -R 755 /home/runner/.memgpt/logs
|
||||
|
||||
- name: Build and run docker dev server
|
||||
env:
|
||||
MEMGPT_PG_DB: memgpt
|
||||
MEMGPT_PG_USER: memgpt
|
||||
MEMGPT_PG_PASSWORD: memgpt
|
||||
MEMGPT_PG_PORT: 8888
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
|
||||
run: docker compose -f dev-compose.yaml up --build -d
|
||||
#- name: "Setup Python, Poetry and Dependencies"
|
||||
# uses: packetcoders/action-setup-cache-python-poetry@v1.2.0
|
||||
# with:
|
||||
# python-version: "3.12"
|
||||
# poetry-version: "1.8.2"
|
||||
# install-args: "--all-extras"
|
||||
|
||||
- name: Wait for service
|
||||
run: bash scripts/wait_for_service.sh http://localhost:8083 -- echo "Service is ready"
|
||||
|
||||
- name: Run tests with pytest
|
||||
env:
|
||||
MEMGPT_PG_DB: memgpt
|
||||
MEMGPT_PG_USER: memgpt
|
||||
MEMGPT_PG_PASSWORD: memgpt
|
||||
MEMGPT_PG_PORT: 8888
|
||||
MEMGPT_SERVER_PASS: test_server_token
|
||||
MEMGPT_SERVER_URL: http://localhost:8083
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
|
||||
run: |
|
||||
pipx install poetry==1.8.2
|
||||
poetry install -E dev
|
||||
poetry run pytest -s tests/test_client.py
|
||||
|
||||
- name: Print docker logs if tests fail
|
||||
if: failure()
|
||||
run: |
|
||||
echo "Printing Docker Logs..."
|
||||
docker compose -f dev-compose.yaml logs
|
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@ -25,8 +25,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: "--all-extras"
|
||||
|
||||
- name: Initialize credentials
|
||||
|
@ -33,6 +33,7 @@ services:
|
||||
- MEMGPT_PG_PASSWORD=${MEMGPT_PG_PASSWORD}
|
||||
- MEMGPT_PG_HOST=pgvector_db
|
||||
- MEMGPT_PG_PORT=5432
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
volumes:
|
||||
- ./configs/server_config.yaml:/root/.memgpt/config # config file
|
||||
- ~/.memgpt/credentials:/root/.memgpt/credentials # credentials file
|
||||
|
@ -7,11 +7,13 @@ human = basic
|
||||
model = gpt-4
|
||||
model_endpoint = https://api.openai.com/v1
|
||||
model_endpoint_type = openai
|
||||
model_wrapper = null
|
||||
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
|
||||
|
||||
|
@ -11,7 +11,7 @@ services:
|
||||
- POSTGRES_PASSWORD=${MEMGPT_PG_PASSWORD}
|
||||
- POSTGRES_DB=${MEMGPT_PG_DB}
|
||||
volumes:
|
||||
- ./.persist/pgdata:/var/lib/postgresql/data
|
||||
- ./.persist/pgdata-test:/var/lib/postgresql/data
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
ports:
|
||||
- "5432:5432"
|
||||
@ -27,8 +27,6 @@ services:
|
||||
ports:
|
||||
- "8083:8083"
|
||||
- "8283:8283"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- MEMGPT_SERVER_PASS=${MEMGPT_SERVER_PASS} # memgpt server password
|
||||
- MEMGPT_PG_DB=${MEMGPT_PG_DB}
|
||||
@ -36,13 +34,7 @@ services:
|
||||
- MEMGPT_PG_PASSWORD=${MEMGPT_PG_PASSWORD}
|
||||
- MEMGPT_PG_HOST=pgvector_db
|
||||
- MEMGPT_PG_PORT=5432
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
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:
|
||||
- "80:80"
|
||||
|
@ -256,7 +256,7 @@ class RESTClient(AbstractClient):
|
||||
}
|
||||
response = requests.post(f"{self.base_url}/api/agents", json=payload, headers=self.headers)
|
||||
if response.status_code != 200:
|
||||
raise ValueError(f"Failed to create agent: {response.text}")
|
||||
raise ValueError(f"Status {response.status_code} - Failed to create agent: {response.text}")
|
||||
response_obj = CreateAgentResponse(**response.json())
|
||||
return self.get_agent_response_to_state(response_obj)
|
||||
|
||||
|
@ -16,7 +16,7 @@ class MemGPTCredentials:
|
||||
|
||||
# openai config
|
||||
openai_auth_type: str = "bearer_token"
|
||||
openai_key: Optional[str] = None
|
||||
openai_key: Optional[str] = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
# gemini config
|
||||
google_ai_key: Optional[str] = None
|
||||
|
@ -55,56 +55,56 @@ def setup_agents_index_router(server: SyncServer, interface: QueuingInterface, p
|
||||
"""
|
||||
interface.clear()
|
||||
|
||||
try:
|
||||
agent_state = server.create_agent(
|
||||
user_id=user_id,
|
||||
# **request.config
|
||||
# TODO turn into a pydantic model
|
||||
name=request.config["name"],
|
||||
preset=request.config["preset"] if "preset" in request.config else None,
|
||||
persona_name=request.config["persona_name"] if "persona_name" in request.config else None,
|
||||
human_name=request.config["human_name"] if "human_name" in request.config else None,
|
||||
persona=request.config["persona"] if "persona" in request.config else None,
|
||||
human=request.config["human"] if "human" in request.config else None,
|
||||
# llm_config=LLMConfigModel(
|
||||
# model=request.config['model'],
|
||||
# )
|
||||
function_names=request.config["function_names"].split(",") if "function_names" in request.config else None,
|
||||
)
|
||||
llm_config = LLMConfigModel(**vars(agent_state.llm_config))
|
||||
embedding_config = EmbeddingConfigModel(**vars(agent_state.embedding_config))
|
||||
# try:
|
||||
agent_state = server.create_agent(
|
||||
user_id=user_id,
|
||||
# **request.config
|
||||
# TODO turn into a pydantic model
|
||||
name=request.config["name"],
|
||||
preset=request.config["preset"] if "preset" in request.config else None,
|
||||
persona_name=request.config["persona_name"] if "persona_name" in request.config else None,
|
||||
human_name=request.config["human_name"] if "human_name" in request.config else None,
|
||||
persona=request.config["persona"] if "persona" in request.config else None,
|
||||
human=request.config["human"] if "human" in request.config else None,
|
||||
# llm_config=LLMConfigModel(
|
||||
# model=request.config['model'],
|
||||
# )
|
||||
function_names=request.config["function_names"].split(",") if "function_names" in request.config else None,
|
||||
)
|
||||
llm_config = LLMConfigModel(**vars(agent_state.llm_config))
|
||||
embedding_config = EmbeddingConfigModel(**vars(agent_state.embedding_config))
|
||||
|
||||
# TODO when get_preset returns a PresetModel instead of Preset, we can remove this packing/unpacking line
|
||||
preset = server.ms.get_preset(name=agent_state.preset, user_id=user_id)
|
||||
# TODO when get_preset returns a PresetModel instead of Preset, we can remove this packing/unpacking line
|
||||
preset = server.ms.get_preset(name=agent_state.preset, user_id=user_id)
|
||||
|
||||
return CreateAgentResponse(
|
||||
agent_state=AgentStateModel(
|
||||
id=agent_state.id,
|
||||
name=agent_state.name,
|
||||
user_id=agent_state.user_id,
|
||||
preset=agent_state.preset,
|
||||
persona=agent_state.persona,
|
||||
human=agent_state.human,
|
||||
llm_config=llm_config,
|
||||
embedding_config=embedding_config,
|
||||
state=agent_state.state,
|
||||
created_at=int(agent_state.created_at.timestamp()),
|
||||
functions_schema=agent_state.state["functions"], # TODO: this is very error prone, jsut lookup the preset instead
|
||||
),
|
||||
preset=PresetModel(
|
||||
name=preset.name,
|
||||
id=preset.id,
|
||||
user_id=preset.user_id,
|
||||
description=preset.description,
|
||||
created_at=preset.created_at,
|
||||
system=preset.system,
|
||||
persona=preset.persona,
|
||||
human=preset.human,
|
||||
functions_schema=preset.functions_schema,
|
||||
),
|
||||
)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
return CreateAgentResponse(
|
||||
agent_state=AgentStateModel(
|
||||
id=agent_state.id,
|
||||
name=agent_state.name,
|
||||
user_id=agent_state.user_id,
|
||||
preset=agent_state.preset,
|
||||
persona=agent_state.persona,
|
||||
human=agent_state.human,
|
||||
llm_config=llm_config,
|
||||
embedding_config=embedding_config,
|
||||
state=agent_state.state,
|
||||
created_at=int(agent_state.created_at.timestamp()),
|
||||
functions_schema=agent_state.state["functions"], # TODO: this is very error prone, jsut lookup the preset instead
|
||||
),
|
||||
preset=PresetModel(
|
||||
name=preset.name,
|
||||
id=preset.id,
|
||||
user_id=preset.user_id,
|
||||
description=preset.description,
|
||||
created_at=preset.created_at,
|
||||
system=preset.system,
|
||||
persona=preset.persona,
|
||||
human=preset.human,
|
||||
functions_schema=preset.functions_schema,
|
||||
),
|
||||
)
|
||||
# except Exception as e:
|
||||
# print(str(e))
|
||||
# raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
return router
|
||||
|
@ -39,10 +39,6 @@ Start the server with:
|
||||
cd memgpt/server/rest_api
|
||||
poetry run uvicorn server:app --reload
|
||||
"""
|
||||
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)
|
||||
|
@ -10,6 +10,7 @@ from typing import Callable, List, Optional, Tuple, Union
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from memgpt.settings import settings
|
||||
import memgpt.constants as constants
|
||||
import memgpt.presets.presets as presets
|
||||
import memgpt.server.utils as server_utils
|
||||
@ -197,9 +198,23 @@ class SyncServer(LockingServer):
|
||||
assert self.config.persona is not None, "Persona must be set in the config"
|
||||
assert self.config.human is not None, "Human must be set in the config"
|
||||
|
||||
# Update storage URI to match passed in settings
|
||||
# TODO: very hack, fix in the future
|
||||
for memory_type in ("archival", "recall", "metadata"):
|
||||
setattr(self.config, f"{memory_type}_storage_uri", settings.pg_uri)
|
||||
self.config.save()
|
||||
|
||||
# TODO figure out how to handle credentials for the server
|
||||
self.credentials = MemGPTCredentials.load()
|
||||
|
||||
# check credentials
|
||||
# TODO: add checks for other providers
|
||||
if (
|
||||
self.config.default_embedding_config.embedding_endpoint_type == "openai"
|
||||
or self.config.default_llm_config.model_endpoint_type == "openai"
|
||||
):
|
||||
assert self.credentials.openai_key is not None, "OpenAI key must be set in the credentials file"
|
||||
|
||||
# Ensure valid database configuration
|
||||
# TODO: add back once tests are matched
|
||||
# assert (
|
||||
@ -665,25 +680,25 @@ class SyncServer(LockingServer):
|
||||
preset_override = True
|
||||
preset_obj.human = human
|
||||
# This is a check for a common bug where users were providing filenames instead of values
|
||||
try:
|
||||
get_human_text(human)
|
||||
raise ValueError(human)
|
||||
raise UserWarning(
|
||||
f"It looks like there is a human file named {human} - did you mean to pass the file contents to the `human` arg?"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
# try:
|
||||
# get_human_text(human)
|
||||
# raise ValueError(human)
|
||||
# raise UserWarning(
|
||||
# f"It looks like there is a human file named {human} - did you mean to pass the file contents to the `human` arg?"
|
||||
# )
|
||||
# except:
|
||||
# pass
|
||||
if persona is not None:
|
||||
preset_override = True
|
||||
preset_obj.persona = persona
|
||||
try:
|
||||
get_persona_text(persona)
|
||||
raise ValueError(persona)
|
||||
raise UserWarning(
|
||||
f"It looks like there is a persona file named {persona} - did you mean to pass the file contents to the `persona` arg?"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
# try:
|
||||
# get_persona_text(persona)
|
||||
# raise ValueError(persona)
|
||||
# raise UserWarning(
|
||||
# f"It looks like there is a persona file named {persona} - did you mean to pass the file contents to the `persona` arg?"
|
||||
# )
|
||||
# except:
|
||||
# pass
|
||||
if human_name is not None and human_name != preset_obj.human_name:
|
||||
preset_override = True
|
||||
preset_obj.human_name = human_name
|
||||
@ -721,8 +736,6 @@ class SyncServer(LockingServer):
|
||||
# gpt-3.5-turbo tends to omit inner monologue, relax this requirement for now
|
||||
first_message_verify_mono=True if (llm_config.model is not None and "gpt-4" in llm_config.model) else False,
|
||||
)
|
||||
save_agent(agent=agent, ms=self.ms)
|
||||
|
||||
# FIXME: this is a hacky way to get the system prompts injected into agent into the DB
|
||||
# self.ms.update_agent(agent.agent_state)
|
||||
except Exception as e:
|
||||
|
88
poetry.lock
generated
88
poetry.lock
generated
@ -1587,13 +1587,13 @@ pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_ve
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.5.35"
|
||||
version = "2.5.36"
|
||||
description = "File identification library for Python"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"},
|
||||
{file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"},
|
||||
{file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"},
|
||||
{file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -3410,13 +3410,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
|
||||
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
|
||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -3619,51 +3619,51 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow"
|
||||
version = "15.0.2"
|
||||
version = "16.0.0"
|
||||
description = "Python library for Apache Arrow"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:88b340f0a1d05b5ccc3d2d986279045655b1fe8e41aba6ca44ea28da0d1455d8"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eaa8f96cecf32da508e6c7f69bb8401f03745c050c1dd42ec2596f2e98deecac"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23c6753ed4f6adb8461e7c383e418391b8d8453c5d67e17f416c3a5d5709afbd"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f639c059035011db8c0497e541a8a45d98a58dbe34dc8fadd0ef128f2cee46e5"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:290e36a59a0993e9a5224ed2fb3e53375770f07379a0ea03ee2fce2e6d30b423"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:06c2bb2a98bc792f040bef31ad3e9be6a63d0cb39189227c08a7d955db96816e"},
|
||||
{file = "pyarrow-15.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:f7a197f3670606a960ddc12adbe8075cea5f707ad7bf0dffa09637fdbb89f76c"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5f8bc839ea36b1f99984c78e06e7a06054693dc2af8920f6fb416b5bca9944e4"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5e81dfb4e519baa6b4c80410421528c214427e77ca0ea9461eb4097c328fa33"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a4f240852b302a7af4646c8bfe9950c4691a419847001178662a98915fd7ee7"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e7d9cfb5a1e648e172428c7a42b744610956f3b70f524aa3a6c02a448ba853e"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2d4f905209de70c0eb5b2de6763104d5a9a37430f137678edfb9a675bac9cd98"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90adb99e8ce5f36fbecbbc422e7dcbcbed07d985eed6062e459e23f9e71fd197"},
|
||||
{file = "pyarrow-15.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:b116e7fd7889294cbd24eb90cd9bdd3850be3738d61297855a71ac3b8124ee38"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:25335e6f1f07fdaa026a61c758ee7d19ce824a866b27bba744348fa73bb5a440"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90f19e976d9c3d8e73c80be84ddbe2f830b6304e4c576349d9360e335cd627fc"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a22366249bf5fd40ddacc4f03cd3160f2d7c247692945afb1899bab8a140ddfb"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2a335198f886b07e4b5ea16d08ee06557e07db54a8400cc0d03c7f6a22f785f"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e6d459c0c22f0b9c810a3917a1de3ee704b021a5fb8b3bacf968eece6df098f"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:033b7cad32198754d93465dcfb71d0ba7cb7cd5c9afd7052cab7214676eec38b"},
|
||||
{file = "pyarrow-15.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:29850d050379d6e8b5a693098f4de7fd6a2bea4365bfd073d7c57c57b95041ee"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:7167107d7fb6dcadb375b4b691b7e316f4368f39f6f45405a05535d7ad5e5058"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e85241b44cc3d365ef950432a1b3bd44ac54626f37b2e3a0cc89c20e45dfd8bf"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:248723e4ed3255fcd73edcecc209744d58a9ca852e4cf3d2577811b6d4b59818"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff3bdfe6f1b81ca5b73b70a8d482d37a766433823e0c21e22d1d7dde76ca33f"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:f3d77463dee7e9f284ef42d341689b459a63ff2e75cee2b9302058d0d98fe142"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:8c1faf2482fb89766e79745670cbca04e7018497d85be9242d5350cba21357e1"},
|
||||
{file = "pyarrow-15.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:28f3016958a8e45a1069303a4a4f6a7d4910643fc08adb1e2e4a7ff056272ad3"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:89722cb64286ab3d4daf168386f6968c126057b8c7ec3ef96302e81d8cdb8ae4"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd0ba387705044b3ac77b1b317165c0498299b08261d8122c96051024f953cd5"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad2459bf1f22b6a5cdcc27ebfd99307d5526b62d217b984b9f5c974651398832"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58922e4bfece8b02abf7159f1f53a8f4d9f8e08f2d988109126c17c3bb261f22"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:adccc81d3dc0478ea0b498807b39a8d41628fa9210729b2f718b78cb997c7c91"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:8bd2baa5fe531571847983f36a30ddbf65261ef23e496862ece83bdceb70420d"},
|
||||
{file = "pyarrow-15.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6669799a1d4ca9da9c7e06ef48368320f5856f36f9a4dd31a11839dda3f6cc8c"},
|
||||
{file = "pyarrow-15.0.2.tar.gz", hash = "sha256:9c9bc803cb3b7bfacc1e96ffbfd923601065d9d3f911179d81e72d99fd74a3d9"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:22a1fdb1254e5095d629e29cd1ea98ed04b4bbfd8e42cc670a6b639ccc208b60"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:574a00260a4ed9d118a14770edbd440b848fcae5a3024128be9d0274dbcaf858"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0815d0ddb733b8c1b53a05827a91f1b8bde6240f3b20bf9ba5d650eb9b89cdf"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df0080339387b5d30de31e0a149c0c11a827a10c82f0c67d9afae3981d1aabb7"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:edf38cce0bf0dcf726e074159c60516447e4474904c0033f018c1f33d7dac6c5"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:91d28f9a40f1264eab2af7905a4d95320ac2f287891e9c8b0035f264fe3c3a4b"},
|
||||
{file = "pyarrow-16.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:99af421ee451a78884d7faea23816c429e263bd3618b22d38e7992c9ce2a7ad9"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d22d0941e6c7bafddf5f4c0662e46f2075850f1c044bf1a03150dd9e189427ce"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:266ddb7e823f03733c15adc8b5078db2df6980f9aa93d6bb57ece615df4e0ba7"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cc23090224b6594f5a92d26ad47465af47c1d9c079dd4a0061ae39551889efe"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56850a0afe9ef37249d5387355449c0f94d12ff7994af88f16803a26d38f2016"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:705db70d3e2293c2f6f8e84874b5b775f690465798f66e94bb2c07bab0a6bb55"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:5448564754c154997bc09e95a44b81b9e31ae918a86c0fcb35c4aa4922756f55"},
|
||||
{file = "pyarrow-16.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:729f7b262aa620c9df8b9967db96c1575e4cfc8c25d078a06968e527b8d6ec05"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:fb8065dbc0d051bf2ae2453af0484d99a43135cadabacf0af588a3be81fbbb9b"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20ce707d9aa390593ea93218b19d0eadab56390311cb87aad32c9a869b0e958c"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5823275c8addbbb50cd4e6a6839952682a33255b447277e37a6f518d6972f4e1"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ab8b9050752b16a8b53fcd9853bf07d8daf19093533e990085168f40c64d978"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:42e56557bc7c5c10d3e42c3b32f6cff649a29d637e8f4e8b311d334cc4326730"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2a7abdee4a4a7cfa239e2e8d721224c4b34ffe69a0ca7981354fe03c1328789b"},
|
||||
{file = "pyarrow-16.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:ef2f309b68396bcc5a354106741d333494d6a0d3e1951271849787109f0229a6"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ed66e5217b4526fa3585b5e39b0b82f501b88a10d36bd0d2a4d8aa7b5a48e2df"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc8814310486f2a73c661ba8354540f17eef51e1b6dd090b93e3419d3a097b3a"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c2f5e239db7ed43e0ad2baf46a6465f89c824cc703f38ef0fde927d8e0955f7"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f293e92d1db251447cb028ae12f7bc47526e4649c3a9924c8376cab4ad6b98bd"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:dd9334a07b6dc21afe0857aa31842365a62eca664e415a3f9536e3a8bb832c07"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d91073d1e2fef2c121154680e2ba7e35ecf8d4969cc0af1fa6f14a8675858159"},
|
||||
{file = "pyarrow-16.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:71d52561cd7aefd22cf52538f262850b0cc9e4ec50af2aaa601da3a16ef48877"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b93c9a50b965ee0bf4fef65e53b758a7e8dcc0c2d86cebcc037aaaf1b306ecc0"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d831690844706e374c455fba2fb8cfcb7b797bfe53ceda4b54334316e1ac4fa4"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35692ce8ad0b8c666aa60f83950957096d92f2a9d8d7deda93fb835e6053307e"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dd3151d098e56f16a8389c1247137f9e4c22720b01c6f3aa6dec29a99b74d80"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:bd40467bdb3cbaf2044ed7a6f7f251c8f941c8b31275aaaf88e746c4f3ca4a7a"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:00a1dcb22ad4ceb8af87f7bd30cc3354788776c417f493089e0a0af981bc8d80"},
|
||||
{file = "pyarrow-16.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:fda9a7cebd1b1d46c97b511f60f73a5b766a6de4c5236f144f41a5d5afec1f35"},
|
||||
{file = "pyarrow-16.0.0.tar.gz", hash = "sha256:59bb1f1edbbf4114c72415f039f1359f1a57d166a331c3229788ccbfbb31689a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
numpy = ">=1.16.6,<2"
|
||||
numpy = ">=1.16.6"
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow-hotfix"
|
||||
|
16
scripts/wait_for_service.sh
Normal file
16
scripts/wait_for_service.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# wait-for-it.sh
|
||||
|
||||
set -e
|
||||
|
||||
host="$1"
|
||||
shift
|
||||
cmd="$@"
|
||||
|
||||
until curl -s "$host" > /dev/null; do
|
||||
>&2 echo "Service is unavailable - sleeping"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
>&2 echo "Service is up - executing command"
|
||||
exec $cmd
|
@ -77,6 +77,8 @@ def run_server():
|
||||
credentials.save()
|
||||
|
||||
# start server
|
||||
from memgpt.server.rest_api.server import start_server
|
||||
|
||||
start_server(debug=True)
|
||||
|
||||
|
||||
|
@ -23,8 +23,6 @@ client = None
|
||||
test_agent_state_post_message = None
|
||||
test_user_id = uuid.uuid4()
|
||||
|
||||
local_service_url = "http://localhost:8283"
|
||||
docker_compose_url = "http://localhost:8083"
|
||||
|
||||
# admin credentials
|
||||
test_server_token = "test_server_token"
|
||||
@ -98,37 +96,41 @@ def run_server():
|
||||
|
||||
# Fixture to create clients with different configurations
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
{"base_url": local_service_url},
|
||||
# {"base_url": docker_compose_url}, # TODO: add when docker compose added to tests
|
||||
# {"base_url": None} # TODO: add when implemented
|
||||
params=[ # whether to use REST API server
|
||||
{"server": True},
|
||||
# {"server": False} # TODO: add when implemented
|
||||
],
|
||||
scope="module",
|
||||
)
|
||||
# @pytest.fixture(params=[{"base_url": test_base_url}], scope="module")
|
||||
def client(request):
|
||||
print("CLIENT", request.param["base_url"])
|
||||
if request.param["base_url"]:
|
||||
if request.param["base_url"] == local_service_url:
|
||||
# start server
|
||||
if request.param["server"]:
|
||||
# get URL from enviornment
|
||||
server_url = os.getenv("MEMGPT_SERVER_URL")
|
||||
if server_url is None:
|
||||
# run server in thread
|
||||
# NOTE: must set MEMGPT_SERVER_PASS enviornment variable
|
||||
server_url = "http://localhost:8283"
|
||||
print("Starting server thread")
|
||||
thread = threading.Thread(target=run_server, daemon=True)
|
||||
thread.start()
|
||||
time.sleep(5)
|
||||
|
||||
admin = Admin(request.param["base_url"], test_server_token)
|
||||
print("Running client tests with server:", server_url)
|
||||
# create user via admin client
|
||||
admin = Admin(server_url, test_server_token)
|
||||
response = admin.create_user(test_user_id) # Adjust as per your client's method
|
||||
response.user_id
|
||||
token = response.api_key
|
||||
else:
|
||||
# use local client (no server)
|
||||
token = None
|
||||
server_url = None
|
||||
|
||||
client = create_client(**request.param, token=token) # This yields control back to the test function
|
||||
client = create_client(base_url=server_url, token=token) # This yields control back to the test function
|
||||
try:
|
||||
yield client
|
||||
finally:
|
||||
# cleanup user
|
||||
if request.param["base_url"]:
|
||||
if server_url:
|
||||
admin.delete_user(test_user_id) # Adjust as per your client's method
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user