Fixed core issues
This commit is contained in:
parent
c4d220a294
commit
03490762be
14 changed files with 190 additions and 31 deletions
|
|
@ -10,10 +10,10 @@ import asyncio
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def start_agent_task_mcp(execution_id):
|
def start_agent_task_mcp(execution_id):
|
||||||
print(f"[start_agent_task_mcp] invoked with execution_id={execution_id}")
|
print(f"invoked with execution_id={execution_id}")
|
||||||
try:
|
try:
|
||||||
execution = AgentExecution.objects.get(uuid=execution_id)
|
execution = AgentExecution.objects.get(uuid=execution_id)
|
||||||
print(f"[start_agent_task_mcp] execution record loaded: agent={execution.agent.uuid}")
|
print(f"execution record loaded: agent={execution.agent.uuid}")
|
||||||
execution.status = 'running'
|
execution.status = 'running'
|
||||||
execution.started_at = timezone.now()
|
execution.started_at = timezone.now()
|
||||||
execution.save()
|
execution.save()
|
||||||
|
|
@ -30,7 +30,7 @@ def start_agent_task_mcp(execution_id):
|
||||||
"content": {
|
"content": {
|
||||||
"execution_id": str(execution.uuid),
|
"execution_id": str(execution.uuid),
|
||||||
"agent_id": str(execution.agent.uuid),
|
"agent_id": str(execution.agent.uuid),
|
||||||
"message": "Agent execution started (via MCP)"
|
"message": "Agent execution started"
|
||||||
},
|
},
|
||||||
"timestamp": timezone.now().isoformat()
|
"timestamp": timezone.now().isoformat()
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +57,7 @@ def start_agent_task_mcp(execution_id):
|
||||||
)
|
)
|
||||||
|
|
||||||
result = asyncio.run(execute_remote())
|
result = asyncio.run(execute_remote())
|
||||||
print(f"[start_agent_task_mcp] MCP result: {result.get('status')}")
|
print(f"MCP result: {result.get('status')}")
|
||||||
|
|
||||||
if result.get('events'):
|
if result.get('events'):
|
||||||
for event in result['events']:
|
for event in result['events']:
|
||||||
|
|
@ -110,7 +110,7 @@ def start_agent_task_mcp(execution_id):
|
||||||
except AgentExecution.DoesNotExist:
|
except AgentExecution.DoesNotExist:
|
||||||
print(f"Execution {execution_id} not found")
|
print(f"Execution {execution_id} not found")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[start_agent_task_mcp] exception: {e}")
|
print(f"exception: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,21 @@
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
|
fyp-postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: ${POSTGRES_CONTAINER_NAME:-fyp-postgres}
|
||||||
|
env_file:
|
||||||
|
- ../../.env
|
||||||
|
environment:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-fyp}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
fyp-redis:
|
fyp-redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
container_name: ${REDIS_CONTAINER_NAME:-fyp-redis}
|
container_name: ${REDIS_CONTAINER_NAME:-fyp-redis}
|
||||||
|
|
@ -41,7 +56,6 @@ services:
|
||||||
- "0.0.0.0:8000:8000"
|
- "0.0.0.0:8000:8000"
|
||||||
volumes:
|
volumes:
|
||||||
- ../../:/app
|
- ../../:/app
|
||||||
- venv:/venv
|
|
||||||
environment:
|
environment:
|
||||||
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-change-in-production}
|
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-change-in-production}
|
||||||
DJANGO_DEBUG: "true"
|
DJANGO_DEBUG: "true"
|
||||||
|
|
@ -49,10 +63,13 @@ services:
|
||||||
DJANGO_CELERY_BROKER_URL: redis://${REDIS_CONTAINER_NAME:-fyp-redis}:6379/0
|
DJANGO_CELERY_BROKER_URL: redis://${REDIS_CONTAINER_NAME:-fyp-redis}:6379/0
|
||||||
DJANGO_CORS_ALLOWED_ORIGINS: http://localhost:5173,http://127.0.0.1:5173
|
DJANGO_CORS_ALLOWED_ORIGINS: http://localhost:5173,http://127.0.0.1:5173
|
||||||
DJANGO_SETTINGS_MODULE: config.settings
|
DJANGO_SETTINGS_MODULE: config.settings
|
||||||
MCP_AGENT_URL: http://mcp-agent-server:8001
|
env_file:
|
||||||
|
- ../../.env
|
||||||
depends_on:
|
depends_on:
|
||||||
fyp-redis:
|
fyp-redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
fyp-postgres:
|
||||||
|
condition: service_healthy
|
||||||
web:
|
web:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
mcp-agent-server:
|
mcp-agent-server:
|
||||||
|
|
@ -65,16 +82,18 @@ services:
|
||||||
container_name: dynavera-celery
|
container_name: dynavera-celery
|
||||||
volumes:
|
volumes:
|
||||||
- ../../:/app
|
- ../../:/app
|
||||||
- venv:/venv
|
|
||||||
- ${USERPROFILE}/.cache/gpt4all:/root/.cache/gpt4all:rw
|
- ${USERPROFILE}/.cache/gpt4all:/root/.cache/gpt4all:rw
|
||||||
environment:
|
environment:
|
||||||
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-change-in-production}
|
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-change-in-production}
|
||||||
DJANGO_CELERY_BROKER_URL: redis://${REDIS_CONTAINER_NAME:-fyp-redis}:6379/0
|
DJANGO_CELERY_BROKER_URL: redis://${REDIS_CONTAINER_NAME:-fyp-redis}:6379/0
|
||||||
DJANGO_SETTINGS_MODULE: config.settings
|
DJANGO_SETTINGS_MODULE: config.settings
|
||||||
MCP_AGENT_URL: http://mcp-agent-server:8001
|
env_file:
|
||||||
|
- ../../.env
|
||||||
depends_on:
|
depends_on:
|
||||||
fyp-redis:
|
fyp-redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
fyp-postgres:
|
||||||
|
condition: service_healthy
|
||||||
mcp-agent-server:
|
mcp-agent-server:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
|
|
||||||
|
|
@ -94,10 +113,15 @@ services:
|
||||||
DJANGO_SETTINGS_MODULE: config.settings
|
DJANGO_SETTINGS_MODULE: config.settings
|
||||||
PYTHONUNBUFFERED: "1"
|
PYTHONUNBUFFERED: "1"
|
||||||
HOME: /root
|
HOME: /root
|
||||||
|
env_file:
|
||||||
|
- ../../.env
|
||||||
depends_on:
|
depends_on:
|
||||||
fyp-redis:
|
fyp-redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
fyp-postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
redis_data:
|
redis_data:
|
||||||
venv:
|
venv:
|
||||||
|
postgres_data:
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ FROM python:3.12-bookworm
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
libpq-dev \
|
libpq-dev \
|
||||||
|
wait-for-it \
|
||||||
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
|
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|
@ -16,4 +17,7 @@ WORKDIR /app
|
||||||
COPY requirements/base.txt .
|
COPY requirements/base.txt .
|
||||||
RUN pip install --no-cache-dir --requirement base.txt
|
RUN pip install --no-cache-dir --requirement base.txt
|
||||||
|
|
||||||
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "config.asgi:application"]
|
COPY ./compose/prod/start /start
|
||||||
|
RUN sed -i 's/\r$//g' /start && chmod +x /start
|
||||||
|
|
||||||
|
CMD ["/start"]
|
||||||
51
compose/prod/docker-compose.local.yml
Normal file
51
compose/prod/docker-compose.local.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
services:
|
||||||
|
fyp-traefik:
|
||||||
|
image: traefik:v2.10
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- "--api.insecure=true"
|
||||||
|
- "--providers.docker=true"
|
||||||
|
- "--providers.docker.exposedbydefault=false"
|
||||||
|
- "--entrypoints.mcp.address=:${MCP_PORT:-58001}"
|
||||||
|
ports:
|
||||||
|
- "${MCP_PORT:-58001}:${MCP_PORT:-58001}"
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
networks:
|
||||||
|
- mcp-internal
|
||||||
|
|
||||||
|
fyp-mcp:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: compose/dev/mcp/Dockerfile
|
||||||
|
container_name: dynavera-mcp-server
|
||||||
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 1
|
||||||
|
env_file:
|
||||||
|
- ../../.env
|
||||||
|
environment:
|
||||||
|
- MCP_HTTP_HOST=0.0.0.0
|
||||||
|
- MCP_HTTP_PORT=8001
|
||||||
|
command: python -m mcp_agent.mcp_server
|
||||||
|
volumes:
|
||||||
|
- ../../:/app
|
||||||
|
- ${USERPROFILE}/.cache/gpt4all:/root/.cache/gpt4all:rw
|
||||||
|
- ../../build/rag_db:/app/build/rag_db:ro
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.fyp-mcp.rule=Host(`${MCP_DOMAIN}`)"
|
||||||
|
- "traefik.http.routers.fyp-mcp.entrypoints=mcp"
|
||||||
|
- "traefik.http.services.fyp-mcp.loadbalancer.server.port=8001"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
- "com.centurylinklabs.watchtower.scope=fyp"
|
||||||
|
networks:
|
||||||
|
- mcp-internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mcp-internal:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,19 @@
|
||||||
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
|
fyp-postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- ../../.env
|
||||||
|
environment:
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
|
||||||
fyp-web:
|
fyp-web:
|
||||||
image: ${IMAGE}
|
image: ${IMAGE}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
@ -66,3 +79,5 @@ volumes:
|
||||||
name: gitlab-runner-config
|
name: gitlab-runner-config
|
||||||
gitlab-machine-config:
|
gitlab-machine-config:
|
||||||
name: gitlab-machine-config
|
name: gitlab-machine-config
|
||||||
|
postgres_data:
|
||||||
|
name: fyp_postgres_data
|
||||||
|
|
@ -4,8 +4,24 @@ set -o errexit
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
|
DB_HOST="${POSTGRES_HOST:-localhost}"
|
||||||
|
DB_PORT="${POSTGRES_PORT:-5432}"
|
||||||
|
|
||||||
|
echo "Waiting for database at ${DB_HOST}:${DB_PORT}..."
|
||||||
|
wait-for-it ${DB_HOST}:${DB_PORT} --timeout=30 --strict || {
|
||||||
|
echo "Timed out waiting for database" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Database is available, continuing startup..."
|
||||||
|
|
||||||
python manage.py makemigrations
|
python manage.py makemigrations
|
||||||
python manage.py migrate
|
python manage.py migrate --noinput
|
||||||
python manage.py loaddata data/site/users.json
|
|
||||||
|
for fixture in /app/data/site/*.json; do
|
||||||
|
echo "Loading fixture: $fixture"
|
||||||
|
python manage.py loaddata "$fixture"
|
||||||
|
done
|
||||||
|
|
||||||
python manage.py collectstatic --noinput
|
python manage.py collectstatic --noinput
|
||||||
exec /usr/local/bin/daphne -b 0.0.0.0 -p 8000 config.asgi:application
|
exec daphne -b 0.0.0.0 -p 8000 config.asgi:application
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -10,6 +10,7 @@ BUILD_DIR = os.getenv('DJANGO_BUILD_DIR', BASE_DIR / 'build')
|
||||||
|
|
||||||
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
|
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
|
||||||
DEBUG = str(os.getenv('DJANGO_DEBUG')).lower() in ('1', 'true', 'yes', 'on')
|
DEBUG = str(os.getenv('DJANGO_DEBUG')).lower() in ('1', 'true', 'yes', 'on')
|
||||||
|
DOMAIN_NAME = os.getenv('DOMAIN_NAME', 'localhost')
|
||||||
|
|
||||||
ALLOWED_HOSTS = [stripped_host for host in os.getenv('DJANGO_ALLOWED_HOSTS', 'localhost').split(',') if (stripped_host:=host.strip())]
|
ALLOWED_HOSTS = [stripped_host for host in os.getenv('DJANGO_ALLOWED_HOSTS', 'localhost').split(',') if (stripped_host:=host.strip())]
|
||||||
|
|
||||||
|
|
@ -76,6 +77,8 @@ CHANNEL_LAYERS = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
|
@ -93,11 +96,11 @@ TEMPLATES = [
|
||||||
|
|
||||||
|
|
||||||
DB_ENGINE = os.getenv('DJANGO_DB_ENGINE', 'django.db.backends.sqlite3')
|
DB_ENGINE = os.getenv('DJANGO_DB_ENGINE', 'django.db.backends.sqlite3')
|
||||||
DB_NAME = os.getenv('DJANGO_DB_NAME', BASE_DIR / 'db.sqlite3')
|
DB_NAME = os.getenv('POSTGRES_DB', BASE_DIR / 'db.sqlite3')
|
||||||
DB_USER = os.getenv('DJANGO_DB_USER')
|
DB_USER = os.getenv('POSTGRES_USER')
|
||||||
DB_PASSWORD = os.getenv('DJANGO_DB_PASSWORD')
|
DB_PASSWORD = os.getenv('POSTGRES_PASSWORD')
|
||||||
DB_HOST = os.getenv('DJANGO_DB_HOST')
|
DB_HOST = os.getenv('POSTGRES_HOST')
|
||||||
DB_PORT = os.getenv('DJANGO_DB_PORT', 5432)
|
DB_PORT = os.getenv('POSTGRES_PORT', 5432)
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|
@ -164,14 +167,32 @@ CELERY_TIMEZONE = 'UTC'
|
||||||
CELERY_TASK_TRACK_STARTED = True
|
CELERY_TASK_TRACK_STARTED = True
|
||||||
CELERY_TASK_TIME_LIMIT = 30 * 60
|
CELERY_TASK_TIME_LIMIT = 30 * 60
|
||||||
|
|
||||||
MCP_AGENT_URL = os.getenv('MCP_AGENT_URL', 'http://localhost:8001')
|
MCP_AGENT_URL = os.getenv('MCP_AGENT_URL')
|
||||||
|
|
||||||
if origins:=os.getenv('DJANGO_CORS_ALLOWED_ORIGINS'):
|
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
||||||
CORS_ALLOWED_ORIGINS = origins.split(',')
|
|
||||||
CORS_ALLOW_CREDENTIALS = True
|
CORS_ALLOW_CREDENTIALS = True
|
||||||
|
CORS_ALLOWED_ORIGINS = [
|
||||||
|
f'http://{DOMAIN_NAME}',
|
||||||
|
f'https://{DOMAIN_NAME}',
|
||||||
|
]
|
||||||
|
CSRF_TRUSTED_ORIGINS = [
|
||||||
|
f'http://{DOMAIN_NAME}',
|
||||||
|
f'https://{DOMAIN_NAME}',
|
||||||
|
]
|
||||||
|
|
||||||
if trusted_origins:=os.getenv('DJANGO_CSRF_TRUSTED_ORIGINS'):
|
|
||||||
CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in trusted_origins.split(',')]
|
CSRF_COOKIE_HTTPONLY = False
|
||||||
|
CSRF_COOKIE_SECURE = not DEBUG
|
||||||
|
CSRF_COOKIE_SAMESITE = 'Lax'
|
||||||
|
|
||||||
|
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||||
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
|
SESSION_COOKIE_SECURE = not DEBUG
|
||||||
|
SESSION_COOKIE_AGE = 1209600
|
||||||
|
SESSION_SAVE_EVERY_REQUEST = True
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
SECURE_CROSS_ORIGIN_OPENER_POLICY = None
|
CORS_ALLOWED_ORIGINS.append(f'http://{DOMAIN_NAME}:5173')
|
||||||
|
CORS_ALLOWED_ORIGINS.append(f'http://{DOMAIN_NAME}:8000')
|
||||||
|
CSRF_TRUSTED_ORIGINS.append(f'http://{DOMAIN_NAME}:5173')
|
||||||
|
CSRF_TRUSTED_ORIGINS.append(f'http://{DOMAIN_NAME}:8000')
|
||||||
|
|
|
||||||
18
data/site/agents.json
Normal file
18
data/site/agents.json
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"model": "agents.agent",
|
||||||
|
"pk": 1,
|
||||||
|
"fields": {
|
||||||
|
"uuid": "bc5ec7f0-a894-420f-b85b-bc799334eca7",
|
||||||
|
"user": 1,
|
||||||
|
"name": "Test Agent",
|
||||||
|
"description": "General Purpose Agent",
|
||||||
|
"status": "idle",
|
||||||
|
"task_id": null,
|
||||||
|
"created_at": "2025-12-20T20:29:57.607Z",
|
||||||
|
"updated_at": "2025-12-20T20:29:57.607Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"avatar_url": "",
|
"avatar_url": "",
|
||||||
"is_active": true,
|
"is_active": true,
|
||||||
"is_staff": true,
|
"is_staff": true,
|
||||||
"role": "employee",
|
"role": "manager",
|
||||||
"groups": [],
|
"groups": [],
|
||||||
"user_permissions": []
|
"user_permissions": []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
<link rel="manifest" href="/site.webmanifest">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Dynavera</title>
|
<title>Dynavera</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
|
||||||
class MCPAgentClient:
|
class MCPAgentClient:
|
||||||
|
|
||||||
def __init__(self, server_url: Optional[str] = None):
|
def __init__(self, server_url: Optional[str] = None):
|
||||||
self.server_url = server_url or getattr(settings, 'MCP_AGENT_URL', 'http://localhost:8001')
|
self.server_url = server_url or getattr(settings, 'MCP_AGENT_URL')
|
||||||
self.http_client = httpx.AsyncClient(
|
self.http_client = httpx.AsyncClient(
|
||||||
timeout=httpx.Timeout(300.0),
|
timeout=httpx.Timeout(300.0),
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
|
|
@ -114,7 +114,7 @@ async def get_mcp_client() -> MCPAgentClient:
|
||||||
|
|
||||||
async with _client_lock:
|
async with _client_lock:
|
||||||
if _mcp_client_instance is None:
|
if _mcp_client_instance is None:
|
||||||
server_url = getattr(settings, 'MCP_AGENT_URL', 'http://localhost:8001')
|
server_url = getattr(settings, 'MCP_AGENT_URL')
|
||||||
_mcp_client_instance = MCPAgentClient(server_url=server_url)
|
_mcp_client_instance = MCPAgentClient(server_url=server_url)
|
||||||
|
|
||||||
return _mcp_client_instance
|
return _mcp_client_instance
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ django-celery-results==2.5.1
|
||||||
django-celery-beat==2.8.1
|
django-celery-beat==2.8.1
|
||||||
gunicorn==23.0.0
|
gunicorn==23.0.0
|
||||||
jinja2==3.1.6
|
jinja2==3.1.6
|
||||||
|
psycopg2-binary==2.9.10
|
||||||
python-dotenv==1.2.1
|
python-dotenv==1.2.1
|
||||||
requests==2.32.5
|
requests==2.32.5
|
||||||
sqlparse==0.5.3
|
sqlparse==0.5.3
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,18 @@ class ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCsrfToken(): string {
|
private getCsrfToken(): string {
|
||||||
const match = document.cookie.match(/(?:^|; )csrftoken=([^;]+)/);
|
let cookieValue = '';
|
||||||
return match ? decodeURIComponent(match[1]) : '';
|
if (document.cookie && document.cookie !== '') {
|
||||||
|
const cookies = document.cookie.split(';');
|
||||||
|
for (let i = 0; i < cookies.length; i++) {
|
||||||
|
const cookie = cookies[i].trim();
|
||||||
|
if (cookie.substring(0, 10) === 'csrftoken=') {
|
||||||
|
cookieValue = decodeURIComponent(cookie.substring(10));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cookieValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private withCsrf(config?: AxiosRequestConfig): AxiosRequestConfig {
|
private withCsrf(config?: AxiosRequestConfig): AxiosRequestConfig {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue