repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | #!/bin/bash |
| #2 | |
| #3 | set -e |
| #4 | |
| #5 | echo "🚀 Starting OpenMemory installation..." |
| #6 | |
| #7 | # Set environment variables |
| #8 | OPENAI_API_KEY="${OPENAI_API_KEY:-}" |
| #9 | USER="${USER:-$(whoami)}" |
| #10 | NEXT_PUBLIC_API_URL="${NEXT_PUBLIC_API_URL:-http://localhost:8765}" |
| #11 | |
| #12 | if [ -z "$OPENAI_API_KEY" ]; then |
| #13 | echo "❌ OPENAI_API_KEY not set. Please run with: curl -sL https://raw.githubusercontent.com/mem0ai/mem0/main/openmemory/run.sh | OPENAI_API_KEY=your_api_key bash" |
| #14 | echo "❌ OPENAI_API_KEY not set. You can also set it as global environment variable: export OPENAI_API_KEY=your_api_key" |
| #15 | exit 1 |
| #16 | fi |
| #17 | |
| #18 | # Check if Docker is installed |
| #19 | if ! command -v docker &> /dev/null; then |
| #20 | echo "❌ Docker not found. Please install Docker first." |
| #21 | exit 1 |
| #22 | fi |
| #23 | |
| #24 | # Check if docker compose is available |
| #25 | if ! docker compose version &> /dev/null; then |
| #26 | echo "❌ Docker Compose not found. Please install Docker Compose V2." |
| #27 | exit 1 |
| #28 | fi |
| #29 | |
| #30 | # Check if the container "mem0_ui" already exists and remove it if necessary |
| #31 | if [ $(docker ps -aq -f name=mem0_ui) ]; then |
| #32 | echo "⚠️ Found existing container 'mem0_ui'. Removing it..." |
| #33 | docker rm -f mem0_ui |
| #34 | fi |
| #35 | |
| #36 | # Find an available port starting from 3000 |
| #37 | echo "🔍 Looking for available port for frontend..." |
| #38 | for port in {3000..3010}; do |
| #39 | if ! lsof -i:$port >/dev/null 2>&1; then |
| #40 | FRONTEND_PORT=$port |
| #41 | break |
| #42 | fi |
| #43 | done |
| #44 | |
| #45 | if [ -z "$FRONTEND_PORT" ]; then |
| #46 | echo "❌ Could not find an available port between 3000 and 3010" |
| #47 | exit 1 |
| #48 | fi |
| #49 | |
| #50 | # Export required variables for Compose and frontend |
| #51 | export OPENAI_API_KEY |
| #52 | export USER |
| #53 | export NEXT_PUBLIC_API_URL |
| #54 | export NEXT_PUBLIC_USER_ID="$USER" |
| #55 | export FRONTEND_PORT |
| #56 | |
| #57 | # Parse vector store selection (env var or flag). Default: qdrant |
| #58 | VECTOR_STORE="${VECTOR_STORE:-qdrant}" |
| #59 | EMBEDDING_DIMS="${EMBEDDING_DIMS:-1536}" |
| #60 | |
| #61 | for arg in "$@"; do |
| #62 | case $arg in |
| #63 | --vector-store=*) |
| #64 | VECTOR_STORE="${arg#*=}" |
| #65 | shift |
| #66 | ;; |
| #67 | --vector-store) |
| #68 | VECTOR_STORE="$2" |
| #69 | shift 2 |
| #70 | ;; |
| #71 | *) |
| #72 | ;; |
| #73 | esac |
| #74 | done |
| #75 | |
| #76 | export VECTOR_STORE |
| #77 | echo "🧰 Using vector store: $VECTOR_STORE" |
| #78 | |
| #79 | # Function to create compose file by merging vector store config with openmemory-mcp service |
| #80 | create_compose_file() { |
| #81 | local vector_store=$1 |
| #82 | local compose_file="compose/${vector_store}.yml" |
| #83 | local volume_name="${vector_store}_data" # Vector-store-specific volume name |
| #84 | |
| #85 | # Check if the compose file exists |
| #86 | if [ ! -f "$compose_file" ]; then |
| #87 | echo "❌ Compose file not found: $compose_file" |
| #88 | echo "Available vector stores: $(ls compose/*.yml | sed 's/compose\///g' | sed 's/\.yml//g' | tr '\n' ' ')" |
| #89 | exit 1 |
| #90 | fi |
| #91 | |
| #92 | echo "📝 Creating docker-compose.yml using $compose_file..." |
| #93 | echo "💾 Using volume: $volume_name" |
| #94 | |
| #95 | # Start the compose file with services section |
| #96 | echo "services:" > docker-compose.yml |
| #97 | |
| #98 | # Extract services from the compose file and replace volume name |
| #99 | # First get everything except the last volumes section |
| #100 | tail -n +2 "$compose_file" | sed '/^volumes:/,$d' | sed "s/mem0_storage/${volume_name}/g" >> docker-compose.yml |
| #101 | |
| #102 | # Add a newline to ensure proper YAML formatting |
| #103 | echo "" >> docker-compose.yml |
| #104 | |
| #105 | # Add the openmemory-mcp service |
| #106 | cat >> docker-compose.yml <<EOF |
| #107 | openmemory-mcp: |
| #108 | image: mem0/openmemory-mcp:latest |
| #109 | environment: |
| #110 | - OPENAI_API_KEY=${OPENAI_API_KEY} |
| #111 | - USER=${USER} |
| #112 | EOF |
| #113 | |
| #114 | # Add vector store specific environment variables |
| #115 | case "$vector_store" in |
| #116 | weaviate) |
| #117 | cat >> docker-compose.yml <<EOF |
| #118 | - WEAVIATE_HOST=mem0_store |
| #119 | - WEAVIATE_PORT=8080 |
| #120 | EOF |
| #121 | ;; |
| #122 | redis) |
| #123 | cat >> docker-compose.yml <<EOF |
| #124 | - REDIS_URL=redis://mem0_store:6379 |
| #125 | EOF |
| #126 | ;; |
| #127 | pgvector) |
| #128 | cat >> docker-compose.yml <<EOF |
| #129 | - PG_HOST=mem0_store |
| #130 | - PG_PORT=5432 |
| #131 | - PG_DB=mem0 |
| #132 | - PG_USER=mem0 |
| #133 | - PG_PASSWORD=mem0 |
| #134 | EOF |
| #135 | ;; |
| #136 | qdrant) |
| #137 | cat >> docker-compose.yml <<EOF |
| #138 | - QDRANT_HOST=mem0_store |
| #139 | - QDRANT_PORT=6333 |
| #140 | EOF |
| #141 | ;; |
| #142 | chroma) |
| #143 | cat >> docker-compose.yml <<EOF |
| #144 | - CHROMA_HOST=mem0_store |
| #145 | - CHROMA_PORT=8000 |
| #146 | EOF |
| #147 | ;; |
| #148 | milvus) |
| #149 | cat >> docker-compose.yml <<EOF |
| #150 | - MILVUS_HOST=mem0_store |
| #151 | - MILVUS_PORT=19530 |
| #152 | EOF |
| #153 | ;; |
| #154 | elasticsearch) |
| #155 | cat >> docker-compose.yml <<EOF |
| #156 | - ELASTICSEARCH_HOST=mem0_store |
| #157 | - ELASTICSEARCH_PORT=9200 |
| #158 | - ELASTICSEARCH_USER=elastic |
| #159 | - ELASTICSEARCH_PASSWORD=changeme |
| #160 | EOF |
| #161 | ;; |
| #162 | faiss) |
| #163 | cat >> docker-compose.yml <<EOF |
| #164 | - FAISS_PATH=/tmp/faiss |
| #165 | EOF |
| #166 | ;; |
| #167 | *) |
| #168 | echo "⚠️ Unknown vector store: $vector_store. Using default Qdrant configuration." |
| #169 | cat >> docker-compose.yml <<EOF |
| #170 | - QDRANT_HOST=mem0_store |
| #171 | - QDRANT_PORT=6333 |
| #172 | EOF |
| #173 | ;; |
| #174 | esac |
| #175 | |
| #176 | # Add common openmemory-mcp service configuration |
| #177 | if [ "$vector_store" = "faiss" ]; then |
| #178 | # FAISS doesn't need a separate service, just volume mounts |
| #179 | cat >> docker-compose.yml <<EOF |
| #180 | ports: |
| #181 | - "8765:8765" |
| #182 | volumes: |
| #183 | - openmemory_db:/usr/src/openmemory |
| #184 | - ${volume_name}:/tmp/faiss |
| #185 | |
| #186 | volumes: |
| #187 | ${volume_name}: |
| #188 | openmemory_db: |
| #189 | EOF |
| #190 | else |
| #191 | cat >> docker-compose.yml <<EOF |
| #192 | depends_on: |
| #193 | - mem0_store |
| #194 | ports: |
| #195 | - "8765:8765" |
| #196 | volumes: |
| #197 | - openmemory_db:/usr/src/openmemory |
| #198 | |
| #199 | volumes: |
| #200 | ${volume_name}: |
| #201 | openmemory_db: |
| #202 | EOF |
| #203 | fi |
| #204 | } |
| #205 | |
| #206 | # Create docker-compose.yml file based on selected vector store |
| #207 | echo "📝 Creating docker-compose.yml..." |
| #208 | create_compose_file "$VECTOR_STORE" |
| #209 | |
| #210 | # Ensure local data directories exist for bind-mounted vector stores |
| #211 | if [ "$VECTOR_STORE" = "milvus" ]; then |
| #212 | echo "🗂️ Ensuring local data directories for Milvus exist..." |
| #213 | mkdir -p ./data/milvus/etcd ./data/milvus/minio ./data/milvus/milvus |
| #214 | fi |
| #215 | |
| #216 | # Function to install vector store specific packages |
| #217 | install_vector_store_packages() { |
| #218 | local vector_store=$1 |
| #219 | echo "📦 Installing packages for vector store: $vector_store..." |
| #220 | |
| #221 | case "$vector_store" in |
| #222 | qdrant) |
| #223 | docker exec openmemory-openmemory-mcp-1 pip install "qdrant-client>=1.9.1" || echo "⚠️ Failed to install qdrant packages" |
| #224 | ;; |
| #225 | chroma) |
| #226 | docker exec openmemory-openmemory-mcp-1 pip install "chromadb>=0.4.24" || echo "⚠️ Failed to install chroma packages" |
| #227 | ;; |
| #228 | weaviate) |
| #229 | docker exec openmemory-openmemory-mcp-1 pip install "weaviate-client>=4.4.0,<4.15.0" || echo "⚠️ Failed to install weaviate packages" |
| #230 | ;; |
| #231 | faiss) |
| #232 | docker exec openmemory-openmemory-mcp-1 pip install "faiss-cpu>=1.7.4" || echo "⚠️ Failed to install faiss packages" |
| #233 | ;; |
| #234 | pgvector) |
| #235 | docker exec openmemory-openmemory-mcp-1 pip install "vecs>=0.4.0" "psycopg>=3.2.8" || echo "⚠️ Failed to install pgvector packages" |
| #236 | ;; |
| #237 | redis) |
| #238 | docker exec openmemory-openmemory-mcp-1 pip install "redis>=5.0.0,<6.0.0" "redisvl>=0.1.0,<1.0.0" || echo "⚠️ Failed to install redis packages" |
| #239 | ;; |
| #240 | elasticsearch) |
| #241 | docker exec openmemory-openmemory-mcp-1 pip install "elasticsearch>=8.0.0,<9.0.0" || echo "⚠️ Failed to install elasticsearch packages" |
| #242 | ;; |
| #243 | milvus) |
| #244 | docker exec openmemory-openmemory-mcp-1 pip install "pymilvus>=2.4.0,<2.6.0" || echo "⚠️ Failed to install milvus packages" |
| #245 | ;; |
| #246 | *) |
| #247 | echo "⚠️ Unknown vector store: $vector_store. Installing default qdrant packages." |
| #248 | docker exec openmemory-openmemory-mcp-1 pip install "qdrant-client>=1.9.1" || echo "⚠️ Failed to install qdrant packages" |
| #249 | ;; |
| #250 | esac |
| #251 | } |
| #252 | |
| #253 | # Start services |
| #254 | echo "🚀 Starting backend services..." |
| #255 | docker compose up -d |
| #256 | |
| #257 | # Wait for container to be ready before installing packages |
| #258 | echo "⏳ Waiting for container to be ready..." |
| #259 | for i in {1..30}; do |
| #260 | if docker exec openmemory-openmemory-mcp-1 python -c "import sys; print('ready')" >/dev/null 2>&1; then |
| #261 | break |
| #262 | fi |
| #263 | sleep 1 |
| #264 | done |
| #265 | |
| #266 | # Install vector store specific packages |
| #267 | install_vector_store_packages "$VECTOR_STORE" |
| #268 | |
| #269 | # If a specific vector store is selected, seed the backend config accordingly |
| #270 | if [ "$VECTOR_STORE" = "milvus" ]; then |
| #271 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #272 | for i in {1..60}; do |
| #273 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #274 | break |
| #275 | fi |
| #276 | sleep 1 |
| #277 | done |
| #278 | |
| #279 | echo "🧩 Configuring vector store (milvus) in backend..." |
| #280 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #281 | -H 'Content-Type: application/json' \ |
| #282 | -d "{\"provider\":\"milvus\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"url\":\"http://mem0_store:19530\",\"token\":\"\",\"db_name\":\"\",\"metric_type\":\"COSINE\"}}" >/dev/null || true |
| #283 | elif [ "$VECTOR_STORE" = "weaviate" ]; then |
| #284 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #285 | for i in {1..60}; do |
| #286 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #287 | break |
| #288 | fi |
| #289 | sleep 1 |
| #290 | done |
| #291 | |
| #292 | echo "🧩 Configuring vector store (weaviate) in backend..." |
| #293 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #294 | -H 'Content-Type: application/json' \ |
| #295 | -d "{\"provider\":\"weaviate\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"cluster_url\":\"http://mem0_store:8080\"}}" >/dev/null || true |
| #296 | elif [ "$VECTOR_STORE" = "redis" ]; then |
| #297 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #298 | for i in {1..60}; do |
| #299 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #300 | break |
| #301 | fi |
| #302 | sleep 1 |
| #303 | done |
| #304 | |
| #305 | echo "🧩 Configuring vector store (redis) in backend..." |
| #306 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #307 | -H 'Content-Type: application/json' \ |
| #308 | -d "{\"provider\":\"redis\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"redis_url\":\"redis://mem0_store:6379\"}}" >/dev/null || true |
| #309 | elif [ "$VECTOR_STORE" = "pgvector" ]; then |
| #310 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #311 | for i in {1..60}; do |
| #312 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #313 | break |
| #314 | fi |
| #315 | sleep 1 |
| #316 | done |
| #317 | |
| #318 | echo "🧩 Configuring vector store (pgvector) in backend..." |
| #319 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #320 | -H 'Content-Type: application/json' \ |
| #321 | -d "{\"provider\":\"pgvector\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"dbname\":\"mem0\",\"user\":\"mem0\",\"password\":\"mem0\",\"host\":\"mem0_store\",\"port\":5432,\"diskann\":false,\"hnsw\":true}}" >/dev/null || true |
| #322 | elif [ "$VECTOR_STORE" = "qdrant" ]; then |
| #323 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #324 | for i in {1..60}; do |
| #325 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #326 | break |
| #327 | fi |
| #328 | sleep 1 |
| #329 | done |
| #330 | |
| #331 | echo "🧩 Configuring vector store (qdrant) in backend..." |
| #332 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #333 | -H 'Content-Type: application/json' \ |
| #334 | -d "{\"provider\":\"qdrant\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"host\":\"mem0_store\",\"port\":6333}}" >/dev/null || true |
| #335 | elif [ "$VECTOR_STORE" = "chroma" ]; then |
| #336 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #337 | for i in {1..60}; do |
| #338 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #339 | break |
| #340 | fi |
| #341 | sleep 1 |
| #342 | done |
| #343 | |
| #344 | echo "🧩 Configuring vector store (chroma) in backend..." |
| #345 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #346 | -H 'Content-Type: application/json' \ |
| #347 | -d "{\"provider\":\"chroma\",\"config\":{\"collection_name\":\"openmemory\",\"host\":\"mem0_store\",\"port\":8000}}" >/dev/null || true |
| #348 | elif [ "$VECTOR_STORE" = "elasticsearch" ]; then |
| #349 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #350 | for i in {1..60}; do |
| #351 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #352 | break |
| #353 | fi |
| #354 | sleep 1 |
| #355 | done |
| #356 | |
| #357 | echo "🧩 Configuring vector store (elasticsearch) in backend..." |
| #358 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #359 | -H 'Content-Type: application/json' \ |
| #360 | -d "{\"provider\":\"elasticsearch\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"host\":\"http://mem0_store\",\"port\":9200,\"user\":\"elastic\",\"password\":\"changeme\",\"verify_certs\":false,\"use_ssl\":false}}" >/dev/null || true |
| #361 | elif [ "$VECTOR_STORE" = "faiss" ]; then |
| #362 | echo "⏳ Waiting for API to be ready at ${NEXT_PUBLIC_API_URL}..." |
| #363 | for i in {1..60}; do |
| #364 | if curl -fsS "${NEXT_PUBLIC_API_URL}/api/v1/config" >/dev/null 2>&1; then |
| #365 | break |
| #366 | fi |
| #367 | sleep 1 |
| #368 | done |
| #369 | |
| #370 | echo "🧩 Configuring vector store (faiss) in backend..." |
| #371 | curl -fsS -X PUT "${NEXT_PUBLIC_API_URL}/api/v1/config/mem0/vector_store" \ |
| #372 | -H 'Content-Type: application/json' \ |
| #373 | -d "{\"provider\":\"faiss\",\"config\":{\"collection_name\":\"openmemory\",\"embedding_model_dims\":${EMBEDDING_DIMS},\"path\":\"/tmp/faiss\",\"distance_strategy\":\"cosine\"}}" >/dev/null || true |
| #374 | fi |
| #375 | |
| #376 | # Start the frontend |
| #377 | echo "🚀 Starting frontend on port $FRONTEND_PORT..." |
| #378 | docker run -d \ |
| #379 | --name mem0_ui \ |
| #380 | -p ${FRONTEND_PORT}:3000 \ |
| #381 | -e NEXT_PUBLIC_API_URL="$NEXT_PUBLIC_API_URL" \ |
| #382 | -e NEXT_PUBLIC_USER_ID="$USER" \ |
| #383 | mem0/openmemory-ui:latest |
| #384 | |
| #385 | echo "✅ Backend: http://localhost:8765" |
| #386 | echo "✅ Frontend: http://localhost:$FRONTEND_PORT" |
| #387 | |
| #388 | # Open the frontend URL in the default web browser |
| #389 | echo "🌐 Opening frontend in the default browser..." |
| #390 | URL="http://localhost:$FRONTEND_PORT" |
| #391 | |
| #392 | if command -v xdg-open > /dev/null; then |
| #393 | xdg-open "$URL" # Linux |
| #394 | elif command -v open > /dev/null; then |
| #395 | open "$URL" # macOS |
| #396 | elif command -v start > /dev/null; then |
| #397 | start "$URL" # Windows (if run via Git Bash or similar) |
| #398 | else |
| #399 | echo "⚠️ Could not detect a method to open the browser. Please open $URL manually." |
| #400 | fi |