[eric] v1.0.14: fix 9Router server.js path, disconnect button, onboarding

This commit is contained in:
ciregenz
2026-03-25 19:17:04 -07:00
parent 1b012d7070
commit bc218c8707
5 changed files with 42 additions and 8 deletions
+22
View File
@@ -273,3 +273,25 @@ async def subscriptions_models():
models = await get_models()
return {"models": models}
@agents.router.post("/subscriptions/disconnect")
async def subscriptions_disconnect(body: dict):
"""Disconnect a subscription provider via 9Router."""
import httpx
provider = body.get("provider", "")
if not provider:
raise HTTPException(status_code=400, detail="provider required")
try:
from backend.apps.nine_router import NINE_ROUTER_API, get_providers
providers_data = await get_providers()
connections = providers_data.get("connections", []) if isinstance(providers_data, dict) else []
conn = next((c for c in connections if c.get("provider") == provider), None)
if conn and conn.get("id"):
async with httpx.AsyncClient(timeout=10.0) as client:
await client.delete(f"{NINE_ROUTER_API}/providers/{conn['id']}")
return {"ok": True}
return {"ok": False, "error": "Connection not found"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
+8 -3
View File
@@ -85,9 +85,14 @@ async def ensure_running():
if _is_packaged and _9router_dir:
# Production mode — use pre-built standalone server
standalone_server = os.path.join(_9router_dir, ".next", "standalone", "server.js")
# In packaged app, build-staging copies .next/standalone/ contents to 9router/
# So server.js is at 9router/server.js (not 9router/.next/standalone/server.js)
standalone_server = os.path.join(_9router_dir, "server.js")
if not os.path.exists(standalone_server):
logger.warning("9Router standalone build not found at %s", standalone_server)
# Fallback: check nested path in case build layout changes
standalone_server = os.path.join(_9router_dir, ".next", "standalone", "server.js")
if not os.path.exists(standalone_server):
logger.warning("9Router standalone build not found in %s", _9router_dir)
return
node = _find_node()
@@ -97,7 +102,7 @@ async def ensure_running():
logger.info("Starting 9Router (production) on port %d...", NINE_ROUTER_PORT)
cmd = [node, standalone_server]
cwd = os.path.join(_9router_dir, ".next", "standalone")
cwd = os.path.dirname(standalone_server)
env = {**os.environ, "PORT": str(NINE_ROUTER_PORT), "NODE_ENV": "production"}
# If using Electron binary as node, enable ELECTRON_RUN_AS_NODE
if node == os.environ.get("OPENSWARM_ELECTRON_PATH"):
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "openswarm",
"version": "1.0.12",
"version": "1.0.13",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openswarm",
"version": "1.0.12",
"version": "1.0.13",
"hasInstallScript": true,
"dependencies": {
"electron-updater": "^6.3.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "openswarm",
"version": "1.0.13",
"version": "1.0.14",
"description": "OpenSwarm — AI Agent Orchestrator",
"main": "main.js",
"scripts": {
+9 -2
View File
@@ -306,8 +306,15 @@ const SubscriptionCards: React.FC = () => {
};
const handleDisconnect = async (providerId: string) => {
// TODO: implement disconnect via 9Router API
fetchStatus();
try {
await fetch(`${API_BASE}/agents/subscriptions/disconnect`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ provider: providerId }),
});
} catch {}
// Wait briefly for 9Router to process, then refresh
setTimeout(fetchStatus, 500);
};
if (!status?.running) {