This commit is contained in:
parent
60ace6b197
commit
3204053681
@ -1,46 +1,56 @@
|
||||
from django.http import JsonResponse
|
||||
from django.views.decorators.http import require_GET
|
||||
|
||||
try:
|
||||
from pxy_contracts.version import SPEC_VERSION
|
||||
except Exception:
|
||||
SPEC_VERSION = '0.1.0'
|
||||
|
||||
@require_GET
|
||||
def agents_list(request):
|
||||
base = request.build_absolute_uri('/')[:-1] # absolute base, no trailing slash
|
||||
agents = [
|
||||
{
|
||||
'agent': 'sami',
|
||||
'name': 'SAMI-Agent',
|
||||
'version': '1.0.0',
|
||||
'spec_version': SPEC_VERSION,
|
||||
'contracts_url': f'{base}/api/contracts/sami.json',
|
||||
'execute_url': f'{base}/api/agents/execute',
|
||||
'description': 'Urban scaling (β,R²) + SAMI residuals + chart',
|
||||
},
|
||||
{
|
||||
'agent': 'sites',
|
||||
'name': 'Sites-Agent',
|
||||
'version': '1.0.0',
|
||||
'spec_version': SPEC_VERSION,
|
||||
'contracts_url': f'{base}/api/contracts/sites.json',
|
||||
'execute_url': f'{base}/api/agents/execute',
|
||||
'description': 'Site scoring (access, demand, competition) with maps',
|
||||
},
|
||||
]
|
||||
return JsonResponse({'agents': agents})
|
||||
# polisplexity/pxy_agents_coral/views.py
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import requests
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.http import JsonResponse
|
||||
|
||||
from django.conf import settings
|
||||
# Internal base where your existing APIs live (same host in MVP)
|
||||
AGENTS_INTERNAL_BASE = getattr(settings, "AGENTS_INTERNAL_BASE", "") # empty = use same host via relative path
|
||||
from django.http import JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_http_methods, require_POST
|
||||
|
||||
# Contracts spec version (best-effort import)
|
||||
try:
|
||||
from pxy_contracts.version import SPEC_VERSION
|
||||
except Exception:
|
||||
SPEC_VERSION = "0.1.0"
|
||||
|
||||
# Where to call your internal APIs from inside the container.
|
||||
# In prod you likely want: "http://127.0.0.1:8002"
|
||||
AGENTS_INTERNAL_BASE = getattr(settings, "AGENTS_INTERNAL_BASE", "")
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["GET", "POST"]) # accept both because the bot posts by default
|
||||
def agents_list(request):
|
||||
"""
|
||||
List available agents (SAMI, Sites) with their contracts & execute endpoints.
|
||||
Accepts GET and POST (POST to support simple bot routers that only POST).
|
||||
"""
|
||||
base = request.build_absolute_uri("/")[:-1] # absolute base, no trailing slash
|
||||
agents = [
|
||||
{
|
||||
"agent": "sami",
|
||||
"name": "SAMI-Agent",
|
||||
"version": "1.0.0",
|
||||
"spec_version": SPEC_VERSION,
|
||||
"contracts_url": f"{base}/api/contracts/sami.json",
|
||||
"execute_url": f"{base}/api/agents/execute",
|
||||
"description": "Urban scaling (β, R²) + SAMI residuals + chart",
|
||||
},
|
||||
{
|
||||
"agent": "sites",
|
||||
"name": "Sites-Agent",
|
||||
"version": "1.0.0",
|
||||
"spec_version": SPEC_VERSION,
|
||||
"contracts_url": f"{base}/api/contracts/sites.json",
|
||||
"execute_url": f"{base}/api/agents/execute",
|
||||
"description": "Site scoring (access, demand, competition) with maps",
|
||||
},
|
||||
]
|
||||
return JsonResponse({"agents": agents})
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_POST
|
||||
@ -51,9 +61,10 @@ def agents_execute(request):
|
||||
Proxies to: /api/sami/run or /api/sites/search
|
||||
"""
|
||||
try:
|
||||
body = json.loads(request.body.decode("utf-8"))
|
||||
body = json.loads(request.body.decode("utf-8") or "{}")
|
||||
agent = (body.get("agent") or "").strip().lower()
|
||||
payload = body.get("payload")
|
||||
|
||||
if agent not in ("sami", "sites"):
|
||||
return JsonResponse(
|
||||
{"code": "AGENT_NOT_FOUND", "message": f"unknown agent '{agent}'"},
|
||||
@ -66,19 +77,19 @@ def agents_execute(request):
|
||||
)
|
||||
|
||||
# Resolve proxy target
|
||||
if agent == "sami":
|
||||
path = "/api/sami/run"
|
||||
else:
|
||||
path = "/api/sites/search"
|
||||
path = "/api/sami/run" if agent == "sami" else "/api/sites/search"
|
||||
|
||||
# Prefer explicit internal base; otherwise same-host absolute URL
|
||||
url = (AGENTS_INTERNAL_BASE or "").rstrip("/") + path
|
||||
# Absolute self-call (same container) using the request host
|
||||
if not url.startswith("http"):
|
||||
base = request.build_absolute_uri("/")[:-1]
|
||||
url = f"{base}{path}"
|
||||
|
||||
# Proxy
|
||||
r = requests.post(url, json=payload, timeout=90)
|
||||
# Pass through JSON and status code
|
||||
|
||||
# Pass through JSON (may be list/dict) & status code
|
||||
# Use safe=False because upstream could return a list
|
||||
return JsonResponse(r.json(), status=r.status_code, safe=False)
|
||||
|
||||
except requests.Timeout:
|
||||
@ -87,11 +98,10 @@ def agents_execute(request):
|
||||
status=504,
|
||||
)
|
||||
except ValueError as ve:
|
||||
return JsonResponse(
|
||||
{"code": "BAD_JSON", "message": str(ve)},
|
||||
status=400,
|
||||
)
|
||||
# Bad JSON in request or from upstream
|
||||
return JsonResponse({"code": "BAD_JSON", "message": str(ve)}, status=400)
|
||||
except Exception as e:
|
||||
# Last-resort error envelope
|
||||
return JsonResponse(
|
||||
{"code": "AGENT_EXEC_ERROR", "message": str(e)},
|
||||
status=500,
|
||||
|
Loading…
x
Reference in New Issue
Block a user