Makefile 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. SHELL=/bin/bash
  2. # Makefile for OpenDevin project
  3. # Variables
  4. DOCKER_IMAGE = ghcr.io/opendevin/sandbox
  5. BACKEND_PORT = 3000
  6. BACKEND_HOST = "127.0.0.1:$(BACKEND_PORT)"
  7. FRONTEND_PORT = 3001
  8. DEFAULT_WORKSPACE_DIR = "./workspace"
  9. DEFAULT_MODEL = "gpt-3.5-turbo-1106"
  10. CONFIG_FILE = config.toml
  11. PRECOMMIT_CONFIG_PATH = "./dev_config/python/.pre-commit-config.yaml"
  12. # ANSI color codes
  13. GREEN=$(shell tput -Txterm setaf 2)
  14. YELLOW=$(shell tput -Txterm setaf 3)
  15. RED=$(shell tput -Txterm setaf 1)
  16. BLUE=$(shell tput -Txterm setaf 6)
  17. RESET=$(shell tput -Txterm sgr0)
  18. # Build
  19. build:
  20. @echo "$(GREEN)Building project...$(RESET)"
  21. @$(MAKE) -s check-dependencies
  22. ifeq ($(SKIP_DOCKER_PULL),)
  23. @$(MAKE) -s pull-docker-image
  24. endif
  25. @$(MAKE) -s install-python-dependencies
  26. @$(MAKE) -s install-frontend-dependencies
  27. @$(MAKE) -s install-precommit-hooks
  28. @$(MAKE) -s build-frontend
  29. @echo "$(GREEN)Build completed successfully.$(RESET)"
  30. check-dependencies:
  31. @echo "$(YELLOW)Checking dependencies...$(RESET)"
  32. @$(MAKE) -s check-system
  33. @$(MAKE) -s check-python
  34. @$(MAKE) -s check-npm
  35. @$(MAKE) -s check-nodejs
  36. ifeq ($(SKIP_DOCKER_PULL),)
  37. @$(MAKE) -s check-docker
  38. endif
  39. @$(MAKE) -s check-poetry
  40. @echo "$(GREEN)Dependencies checked successfully.$(RESET)"
  41. check-system:
  42. @echo "$(YELLOW)Checking system...$(RESET)"
  43. @if [ "$(shell uname)" = "Darwin" ]; then \
  44. echo "$(BLUE)macOS detected.$(RESET)"; \
  45. elif [ "$(shell uname)" = "Linux" ]; then \
  46. echo "$(BLUE)Linux detected.$(RESET)"; \
  47. elif [ "$$(uname -r | grep -i microsoft)" ]; then \
  48. echo "$(BLUE)Windows Subsystem for Linux detected.$(RESET)"; \
  49. else \
  50. echo "$(RED)Unsupported system detected. Please use macOS, Linux, or Windows Subsystem for Linux (WSL).$(RESET)"; \
  51. exit 1; \
  52. fi
  53. check-python:
  54. @echo "$(YELLOW)Checking Python installation...$(RESET)"
  55. @if command -v python3.11 > /dev/null; then \
  56. echo "$(BLUE)$(shell python3.11 --version) is already installed.$(RESET)"; \
  57. else \
  58. echo "$(RED)Python 3.11 is not installed. Please install Python 3.11 to continue.$(RESET)"; \
  59. exit 1; \
  60. fi
  61. check-npm:
  62. @echo "$(YELLOW)Checking npm installation...$(RESET)"
  63. @if command -v npm > /dev/null; then \
  64. echo "$(BLUE)npm $(shell npm --version) is already installed.$(RESET)"; \
  65. else \
  66. echo "$(RED)npm is not installed. Please install Node.js to continue.$(RESET)"; \
  67. exit 1; \
  68. fi
  69. check-nodejs:
  70. @echo "$(YELLOW)Checking Node.js installation...$(RESET)"
  71. @if command -v node > /dev/null; then \
  72. NODE_VERSION=$(shell node --version | sed -E 's/v//g'); \
  73. IFS='.' read -r -a NODE_VERSION_ARRAY <<< "$$NODE_VERSION"; \
  74. if [ "$${NODE_VERSION_ARRAY[0]}" -gt 18 ] || ([ "$${NODE_VERSION_ARRAY[0]}" -eq 18 ] && [ "$${NODE_VERSION_ARRAY[1]}" -gt 17 ]) || ([ "$${NODE_VERSION_ARRAY[0]}" -eq 18 ] && [ "$${NODE_VERSION_ARRAY[1]}" -eq 17 ] && [ "$${NODE_VERSION_ARRAY[2]}" -ge 1 ]); then \
  75. echo "$(BLUE)Node.js $$NODE_VERSION is already installed.$(RESET)"; \
  76. else \
  77. echo "$(RED)Node.js 18.17.1 or later is required. Please install Node.js 18.17.1 or later to continue.$(RESET)"; \
  78. exit 1; \
  79. fi; \
  80. else \
  81. echo "$(RED)Node.js is not installed. Please install Node.js to continue.$(RESET)"; \
  82. exit 1; \
  83. fi
  84. check-docker:
  85. @echo "$(YELLOW)Checking Docker installation...$(RESET)"
  86. @if command -v docker > /dev/null; then \
  87. echo "$(BLUE)$(shell docker --version) is already installed.$(RESET)"; \
  88. else \
  89. echo "$(RED)Docker is not installed. Please install Docker to continue.$(RESET)"; \
  90. exit 1; \
  91. fi
  92. check-poetry:
  93. @echo "$(YELLOW)Checking Poetry installation...$(RESET)"
  94. @if command -v poetry > /dev/null; then \
  95. POETRY_VERSION=$(shell poetry --version 2>&1 | sed -E 's/Poetry \(version ([0-9]+\.[0-9]+\.[0-9]+)\)/\1/'); \
  96. IFS='.' read -r -a POETRY_VERSION_ARRAY <<< "$$POETRY_VERSION"; \
  97. if [ $${POETRY_VERSION_ARRAY[0]} -ge 1 ] && [ $${POETRY_VERSION_ARRAY[1]} -ge 8 ]; then \
  98. echo "$(BLUE)$(shell poetry --version) is already installed.$(RESET)"; \
  99. else \
  100. echo "$(RED)Poetry 1.8 or later is required. You can install poetry by running the following command, then adding Poetry to your PATH:"; \
  101. echo "$(RED) curl -sSL https://install.python-poetry.org | python3 -$(RESET)"; \
  102. echo "$(RED)More detail here: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
  103. exit 1; \
  104. fi; \
  105. else \
  106. echo "$(RED)Poetry is not installed. You can install poetry by running the following command, then adding Poetry to your PATH:"; \
  107. echo "$(RED) curl -sSL https://install.python-poetry.org | python3.11 -$(RESET)"; \
  108. echo "$(RED)More detail here: https://python-poetry.org/docs/#installing-with-the-official-installer$(RESET)"; \
  109. exit 1; \
  110. fi
  111. pull-docker-image:
  112. @echo "$(YELLOW)Pulling Docker image...$(RESET)"
  113. @docker pull $(DOCKER_IMAGE)
  114. @echo "$(GREEN)Docker image pulled successfully.$(RESET)"
  115. install-python-dependencies:
  116. @echo "$(GREEN)Installing Python dependencies...$(RESET)"
  117. @if [ "$(shell uname)" = "Darwin" ]; then \
  118. echo "$(BLUE)Installing `chroma-hnswlib`...$(RESET)"; \
  119. export HNSWLIB_NO_NATIVE=1; \
  120. poetry run pip install chroma-hnswlib; \
  121. fi
  122. @poetry install --without evaluation
  123. @poetry run playwright install --with-deps chromium
  124. @echo "$(GREEN)Python dependencies installed successfully.$(RESET)"
  125. install-frontend-dependencies:
  126. @echo "$(YELLOW)Setting up frontend environment...$(RESET)"
  127. @echo "$(YELLOW)Detect Node.js version...$(RESET)"
  128. @cd frontend && node ./scripts/detect-node-version.js
  129. @cd frontend && \
  130. echo "$(BLUE)Installing frontend dependencies with npm...$(RESET)" && \
  131. npm install && \
  132. echo "$(BLUE)Running make-i18n with npm...$(RESET)" && \
  133. npm run make-i18n
  134. @echo "$(GREEN)Frontend dependencies installed successfully.$(RESET)"
  135. install-precommit-hooks:
  136. @echo "$(YELLOW)Installing pre-commit hooks...$(RESET)"
  137. @git config --unset-all core.hooksPath || true
  138. @poetry run pre-commit install --config $(PRECOMMIT_CONFIG_PATH)
  139. @echo "$(GREEN)Pre-commit hooks installed successfully.$(RESET)"
  140. lint:
  141. @echo "$(YELLOW)Running linters...$(RESET)"
  142. @poetry run pre-commit run --all-files --show-diff-on-failure --config $(PRECOMMIT_CONFIG_PATH)
  143. build-frontend:
  144. @echo "$(YELLOW)Building frontend...$(RESET)"
  145. @cd frontend && npm run build
  146. # Start backend
  147. start-backend:
  148. @echo "$(YELLOW)Starting backend...$(RESET)"
  149. @poetry run uvicorn opendevin.server.listen:app --port $(BACKEND_PORT) --reload --reload-exclude workspace/*
  150. # Start frontend
  151. start-frontend:
  152. @echo "$(YELLOW)Starting frontend...$(RESET)"
  153. @cd frontend && VITE_BACKEND_HOST=$(BACKEND_HOST) VITE_FRONTEND_PORT=$(FRONTEND_PORT) npm run start
  154. # Run the app
  155. run:
  156. @echo "$(YELLOW)Running the app...$(RESET)"
  157. @if [ "$(OS)" = "Windows_NT" ]; then \
  158. echo "$(RED)`make run` is not supported on Windows. Please run `make start-frontend` and `make start-backend` separately.$(RESET)"; \
  159. exit 1; \
  160. fi
  161. @mkdir -p logs
  162. @echo "$(YELLOW)Starting backend server...$(RESET)"
  163. @poetry run uvicorn opendevin.server.listen:app --port $(BACKEND_PORT) &
  164. @echo "$(YELLOW)Waiting for the backend to start...$(RESET)"
  165. @until nc -z localhost $(BACKEND_PORT); do sleep 0.1; done
  166. @echo "$(GREEN)Backend started successfully.$(RESET)"
  167. @cd frontend && echo "$(BLUE)Starting frontend with npm...$(RESET)" && npm run start -- --port $(FRONTEND_PORT)
  168. @echo "$(GREEN)Application started successfully.$(RESET)"
  169. # Setup config.toml
  170. setup-config:
  171. @echo "$(YELLOW)Setting up config.toml...$(RESET)"
  172. @$(MAKE) setup-config-prompts
  173. @mv $(CONFIG_FILE).tmp $(CONFIG_FILE)
  174. @echo "$(GREEN)Config.toml setup completed.$(RESET)"
  175. setup-config-prompts:
  176. @read -p "Enter your LLM Model name, used for running without UI. Set the model in the UI after you start the app. (see https://docs.litellm.ai/docs/providers for full list) [default: $(DEFAULT_MODEL)]: " llm_model; \
  177. llm_model=$${llm_model:-$(DEFAULT_MODEL)}; \
  178. echo "LLM_MODEL=\"$$llm_model\"" > $(CONFIG_FILE).tmp
  179. @read -p "Enter your LLM API key: " llm_api_key; \
  180. echo "LLM_API_KEY=\"$$llm_api_key\"" >> $(CONFIG_FILE).tmp
  181. @read -p "Enter your LLM Base URL [mostly used for local LLMs, leave blank if not needed - example: http://localhost:5001/v1/]: " llm_base_url; \
  182. if [[ ! -z "$$llm_base_url" ]]; then echo "LLM_BASE_URL=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; fi
  183. @echo "Enter your LLM Embedding Model"; \
  184. echo "Choices are:"; \
  185. echo " - openai"; \
  186. echo " - azureopenai"; \
  187. echo " - Embeddings available only with OllamaEmbedding:"; \
  188. echo " - llama2"; \
  189. echo " - mxbai-embed-large"; \
  190. echo " - nomic-embed-text"; \
  191. echo " - all-minilm"; \
  192. echo " - stable-code"; \
  193. echo " - Leave blank to default to 'BAAI/bge-small-en-v1.5' via huggingface"; \
  194. read -p "> " llm_embedding_model; \
  195. echo "LLM_EMBEDDING_MODEL=\"$$llm_embedding_model\"" >> $(CONFIG_FILE).tmp; \
  196. if [ "$$llm_embedding_model" = "llama2" ] || [ "$$llm_embedding_model" = "mxbai-embed-large" ] || [ "$$llm_embedding_model" = "nomic-embed-text" ] || [ "$$llm_embedding_model" = "all-minilm" ] || [ "$$llm_embedding_model" = "stable-code" ]; then \
  197. read -p "Enter the local model URL for the embedding model (will set LLM_EMBEDDING_BASE_URL): " llm_embedding_base_url; \
  198. echo "LLM_EMBEDDING_BASE_URL=\"$$llm_embedding_base_url\"" >> $(CONFIG_FILE).tmp; \
  199. elif [ "$$llm_embedding_model" = "azureopenai" ]; then \
  200. read -p "Enter the Azure endpoint URL (will overwrite LLM_BASE_URL): " llm_base_url; \
  201. echo "LLM_BASE_URL=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; \
  202. read -p "Enter the Azure LLM Embedding Deployment Name: " llm_embedding_deployment_name; \
  203. echo "LLM_EMBEDDING_DEPLOYMENT_NAME=\"$$llm_embedding_deployment_name\"" >> $(CONFIG_FILE).tmp; \
  204. read -p "Enter the Azure API Version: " llm_api_version; \
  205. echo "LLM_API_VERSION=\"$$llm_api_version\"" >> $(CONFIG_FILE).tmp; \
  206. fi
  207. @read -p "Enter your workspace directory [default: $(DEFAULT_WORKSPACE_DIR)]: " workspace_dir; \
  208. workspace_dir=$${workspace_dir:-$(DEFAULT_WORKSPACE_DIR)}; \
  209. echo "WORKSPACE_BASE=\"$$workspace_dir\"" >> $(CONFIG_FILE).tmp
  210. # Clean up all caches
  211. clean:
  212. @echo "$(YELLOW)Cleaning up caches...$(RESET)"
  213. @rm -rf opendevin/.cache
  214. @echo "$(GREEN)Caches cleaned up successfully.$(RESET)"
  215. # Help
  216. help:
  217. @echo "$(BLUE)Usage: make [target]$(RESET)"
  218. @echo "Targets:"
  219. @echo " $(GREEN)build$(RESET) - Build project, including environment setup and dependencies."
  220. @echo " $(GREEN)lint$(RESET) - Run linters on the project."
  221. @echo " $(GREEN)setup-config$(RESET) - Setup the configuration for OpenDevin by providing LLM API key,"
  222. @echo " LLM Model name, and workspace directory."
  223. @echo " $(GREEN)start-backend$(RESET) - Start the backend server for the OpenDevin project."
  224. @echo " $(GREEN)start-frontend$(RESET) - Start the frontend server for the OpenDevin project."
  225. @echo " $(GREEN)run$(RESET) - Run the OpenDevin application, starting both backend and frontend servers."
  226. @echo " Backend Log file will be stored in the 'logs' directory."
  227. @echo " $(GREEN)help$(RESET) - Display this help message, providing information on available targets."
  228. # Phony targets
  229. .PHONY: build check-dependencies check-python check-npm check-docker check-poetry pull-docker-image install-python-dependencies install-frontend-dependencies install-precommit-hooks lint start-backend start-frontend run setup-config setup-config-prompts help