Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c269cf5e5 |
@@ -889,6 +889,29 @@ def add_studio_home_routes(routes: web.RouteTableDef, server) -> None:
|
||||
org = _org_of(request)
|
||||
return web.json_response(await _wallet(request, org))
|
||||
|
||||
@routes.post("/v1/agent")
|
||||
async def agent_bridge(request: web.Request):
|
||||
"""Same-origin bridge to the cloud agent orchestrator. The session cookie
|
||||
stays host-only (never widened to *.hanzo.ai); this forwards the caller's
|
||||
bearer server-side — the wallet pattern. Direct-to-gateway remains
|
||||
available to the SPA via VITE_AGENT_API."""
|
||||
from middleware.gpu_dispatch import CLOUD, _bearer
|
||||
tok = _bearer(request)
|
||||
if not tok:
|
||||
return web.json_response({"error": "auth required"}, status=401)
|
||||
body = await request.read()
|
||||
if len(body) > 1 << 20:
|
||||
return web.json_response({"error": "body too large"}, status=413)
|
||||
try:
|
||||
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=180)) as s:
|
||||
async with s.post(f"{CLOUD}/v1/agent", data=body,
|
||||
headers={"Authorization": tok,
|
||||
"Content-Type": "application/json"}) as r:
|
||||
return web.Response(status=r.status, body=await r.read(),
|
||||
content_type="application/json")
|
||||
except Exception:
|
||||
return web.json_response({"error": "agent unreachable"}, status=502)
|
||||
|
||||
@routes.get("/v1/library")
|
||||
async def get_library(request: web.Request):
|
||||
org = _org_of(request)
|
||||
|
||||
Vendored
+5
-1
@@ -10,7 +10,11 @@
|
||||
// VITE_STUDIO_API / VITE_AGENT_API override the bases for local dev.
|
||||
|
||||
const BASE = (import.meta.env.VITE_STUDIO_API ?? '').replace(/\/$/, '')
|
||||
const AGENT_API = (import.meta.env.VITE_AGENT_API ?? 'https://api.hanzo.ai').replace(/\/$/, '')
|
||||
// Default: same-origin through the studio's /v1/agent bridge — the host-only
|
||||
// session cookie authorizes it and the middleware forwards the bearer, so no
|
||||
// parent-domain cookie and no gateway CORS dependency. VITE_AGENT_API points
|
||||
// straight at the gateway for direct mode.
|
||||
const AGENT_API = (import.meta.env.VITE_AGENT_API ?? '').replace(/\/$/, '')
|
||||
|
||||
async function j<T>(url: string, init?: RequestInit): Promise<T> {
|
||||
const r = await fetch(url, { credentials: 'include', ...init })
|
||||
|
||||
Reference in New Issue
Block a user