diff --git a/.env.example b/.env.example index 7cf366d..52ba1ee 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ REDIS_BASE_URL="redis://redis:6379/0" WORK_DIR="/Users/username/Documents/workspace_with_my_files" OLLAMA_PORT="11434" LM_STUDIO_PORT="1234" +BACKEND_PORT="7777" CUSTOM_ADDITIONAL_LLM_PORT="11435" OPENAI_API_KEY='xxxxx' DEEPSEEK_API_KEY='xxxxx' diff --git a/api.py b/api.py index 9e70a4a..425fc72 100755 --- a/api.py +++ b/api.py @@ -255,5 +255,5 @@ if __name__ == "__main__": if envport: port = int(envport) else: - port = 8000 - uvicorn.run(api, host="0.0.0.0", port=8000) \ No newline at end of file + port = 7777 + uvicorn.run(api, host="0.0.0.0", port=7777) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 5cd548d..cf6ad29 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,7 +65,7 @@ services: environment: - NODE_ENV=development - CHOKIDAR_USEPOLLING=true - - REACT_APP_BACKEND_URL=http://0.0.0.0:${BACKEND_PORT:-8000} + - REACT_APP_BACKEND_URL=http://host.docker.internal:${BACKEND_PORT:-7777} networks: - agentic-seek-net @@ -88,6 +88,8 @@ services: - SEARXNG_URL=${SEARXNG_BASE_URL:-http://searxng:8080} - REDIS_URL=${REDIS_BASE_URL:-redis://redis:6379/0} - WORK_DIR=/opt/workspace + - BACKEND_PORT=${BACKEND_PORT} + - DOCKER_INTERNAL_URL=http://host.docker.internal - OPENAI_API_KEY=${OPENAI_API_KEY} - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} @@ -96,7 +98,10 @@ services: - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - HUGGINGFACE_API_KEY=${HUGGINGFACE_API_KEY} - DSK_DEEPSEEK_API_KEY=${DSK_DEEPSEEK_API_KEY} - network_mode: "host" + networks: + - agentic-seek-net + extra_hosts: + - "host.docker.internal:host-gateway" volumes: redis-data: diff --git a/frontend/agentic-seek-front/src/App.js b/frontend/agentic-seek-front/src/App.js index ed64d08..b456e79 100644 --- a/frontend/agentic-seek-front/src/App.js +++ b/frontend/agentic-seek-front/src/App.js @@ -4,7 +4,8 @@ import axios from 'axios'; import './App.css'; import { colors } from './colors'; -const BACKEND_URL = process.env.BACKEND_PORT || 'http://0.0.0.0:8000'; +const BACKEND_URL = 'http://localhost:7777' || process.env.REACT_APP_BACKEND_URL; +console.log('Using backend URL:', BACKEND_URL); function App() { const [query, setQuery] = useState(''); diff --git a/sources/llm_provider.py b/sources/llm_provider.py index da43d95..cae1665 100644 --- a/sources/llm_provider.py +++ b/sources/llm_provider.py @@ -36,6 +36,7 @@ class Provider: } self.logger = Logger("provider.log") self.api_key = None + self.internal_url, self.in_docker = self.get_internal_url() self.unsafe_providers = ["openai", "deepseek", "dsk_deepseek", "together", "google", "openrouter"] if self.provider_name not in self.available_providers: raise ValueError(f"Unknown provider: {provider_name}") @@ -56,6 +57,13 @@ class Provider: pretty_print(f"API key {api_key_var} not found in .env file. Please add it", color="warning") exit(1) return api_key + + def get_internal_url(self): + load_dotenv() + url = os.getenv("DOCKER_INTERNAL_URL") + if not url: # running on host + return "http://localhost", False + return url, True def respond(self, history, verbose=True): """ @@ -152,7 +160,7 @@ class Provider: Use local or remote Ollama server to generate text. """ thought = "" - host = "http://localhost:11434" if self.is_local else f"http://{self.server_address}" + host = f"{self.internal_url}:11434" if self.is_local else f"http://{self.server_address}" client = OllamaClient(host=host) try: @@ -203,7 +211,13 @@ class Provider: Use openai to generate text. """ base_url = self.server_ip - if self.is_local: + if self.is_local and self.in_docker: + try: + host, port = base_url.split(':') + except Exception as e: + port = "8000" + client = OpenAI(api_key=self.api_key, base_url=f"{self.internal_url}:{port}") + elif self.is_local: client = OpenAI(api_key=self.api_key, base_url=f"http://{base_url}") else: client = OpenAI(api_key=self.api_key) @@ -326,7 +340,8 @@ class Provider: lm studio use endpoint /v1/chat/completions not /chat/completions like openai """ thought = "" - route_start = f"{self.server_ip}/v1/chat/completions" + url = self.internal_url if self.in_docker else self.server_ip + route_start = f"{url}/v1/chat/completions" payload = { "messages": history, "temperature": 0.7, diff --git a/start_services.cmd b/start_services.cmd index ce278a8..d4d1102 100644 --- a/start_services.cmd +++ b/start_services.cmd @@ -3,26 +3,24 @@ if "%1"=="full" ( echo Starting full deployment... ) else ( - echo Starting partial deployment... (backend run on host), use "full" to run all services in containers + set "msg=Starting partial deployment... (backend run on host), use "full" to run all services in containers" + echo !msg! ) + where openssl >nul 2>&1 if %ERRORLEVEL% == 0 ( for /f %%i in ('openssl rand -hex 32') do set SEARXNG_SECRET_KEY=%%i ) else ( - where python3 >nul 2>&1 + where python >nul 2>&1 if %ERRORLEVEL% == 0 ( - for /f %%i in ('python3 -c "import secrets; print(secrets.token_hex(32))"') do set SEARXNG_SECRET_KEY=%%i + for /f %%i in ('python -c "import secrets; print(secrets.token_hex(32))"') do set SEARXNG_SECRET_KEY=%%i ) else ( echo Error: Neither openssl nor python is available to generate a secret key. - exit /b 1 + exit /b 2 ) ) -REM Stop all containers -echo Stopping containers... -docker stop $(docker ps -aq) >nul 2>&1 - REM Generate secret key for /f %%i in ('powershell -command "[System.Web.Security.Membership]::GeneratePassword(64,0)"') do set SEARXNG_SECRET_KEY=%%i