feat: add guided exploration and share user-started MCP backend

This commit is contained in:
chenmingxuan committed 2026-10-16 18:32:46 +08:00
1 parent f86db1ced6
commit ee256ad7ce
144 files changed
+8625 -2075

No files matched your search

+62 -26
View File
@@ -46,7 +46,7 @@ for _p in (str(_workspace_root), str(_apps_dir), str(_admin_console_dir), str(_c
if _p not in sys.path:
sys.path.insert(0, _p)
from fastapi import FastAPI
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import FileResponse, HTMLResponse
import uvicorn
@@ -71,28 +71,18 @@ from artemis.config import (
)
from artemis.resources import get_bundled_showcase_dist
try:
from admin_console.core.security import SameOriginBoundaryMiddleware
from admin_console.core.state import ServerState, state
from admin_console.database.connection import db_session, get_db
from admin_console.database.repositories.session_repository import session_repo
from admin_console.database.repositories.step_repository import step_repo
from admin_console.database.repositories.trace_repository import trace_repo
from admin_console.routers import media, replay, sessions, steps, stream, system, tasks
from admin_console.routers.replay import replay_manager
from admin_console.services.ipc_service import ipc_service
from admin_console.services.media_service import media_service
from admin_console.services.model_service import model_service
from admin_console.services.task_queue_service import task_queue_service
except ImportError:
from apps.admin_console.core.security import SameOriginBoundaryMiddleware
from apps.admin_console.core.state import state
from apps.admin_console.database.repositories.session_repository import session_repo
from apps.admin_console.routers import media, replay, sessions, steps, stream, system, tasks
from apps.admin_console.routers.replay import replay_manager
from apps.admin_console.services.ipc_service import ipc_service
from apps.admin_console.services.model_service import model_service
from apps.admin_console.services.task_queue_service import task_queue_service
from apps.admin_console.core.security import SameOriginBoundaryMiddleware
from apps.admin_console.core.state import ServerState, state
from apps.admin_console.database.connection import db_session, get_db
from apps.admin_console.database.repositories.session_repository import session_repo
from apps.admin_console.database.repositories.step_repository import step_repo
from apps.admin_console.database.repositories.trace_repository import trace_repo
from apps.admin_console.routers import media, replay, sessions, steps, stream, system, tasks
from apps.admin_console.routers.replay import replay_manager
from apps.admin_console.services.ipc_service import ipc_service
from apps.admin_console.services.media_service import media_service
from apps.admin_console.services.model_service import model_service
from apps.admin_console.services.task_queue_service import task_queue_service
# Initialize language server synchronization address
init_ls_address()
@@ -101,11 +91,33 @@ init_ls_address()
@asynccontextmanager
async def _lifespan(_app: "FastAPI"):
"""Start server resources and release them on shutdown."""
await on_startup()
from artemis.config.paths import get_app_dir, get_traces_dir
from artemis.runtime.daemon_client import configure_local_daemon
from artemis.service_registry import ServiceRegistration
registration = ServiceRegistration(
port=state.port,
token=LIFECYCLE_TOKEN,
app_dir=get_app_dir(),
traces_dir=get_traces_dir(),
)
registration.acquire()
app.state.service_registration = registration
configure_local_daemon(state.port)
try:
yield
shared_tool_executor.start()
async with shared_mcp.session_manager.run():
await on_startup()
try:
yield
finally:
await on_shutdown()
finally:
await on_shutdown()
try:
await shared_tool_executor.stop()
finally:
configure_local_daemon(None)
registration.close()
# Initialize FastAPI application
@@ -118,6 +130,26 @@ app.state.lifecycle_token = LIFECYCLE_TOKEN
# and unrecognized Host headers (DNS rebinding) instead.
app.add_middleware(SameOriginBoundaryMiddleware)
from mcp_server.shared import LocalMcpBoundary, create_shared_mcp
shared_mcp, shared_tool_executor = create_shared_mcp()
app.mount("/api/mcp", LocalMcpBoundary(shared_mcp.streamable_http_app(), LIFECYCLE_TOKEN))
@app.get("/api/system/shared-service")
async def shared_service_identity(request: Request):
"""Authenticated identity probe for local connection-only MCP bridges."""
import hmac
from artemis.service_registry import TOKEN_HEADER
if not hmac.compare_digest(request.headers.get(TOKEN_HEADER, ""), LIFECYCLE_TOKEN):
raise HTTPException(status_code=403, detail="Invalid service token")
registration = getattr(app.state, "service_registration", None)
if registration is None:
raise HTTPException(status_code=503, detail="Service is starting")
return {key: registration.info[key] for key in ("protocol", "installation", "instance", "pid")}
async def on_startup():
"""Startup lifecycle hooks."""
@@ -246,6 +278,10 @@ from apps.admin_console.routers.plugins import router as plugins_router
app.include_router(plugins_router)
from apps.admin_console.routers.exploration import router as exploration_router
app.include_router(exploration_router)
# Mount cloud gateway router for Frappe / Cloud integration if present
try:
from cloud_service.gateway import cloud_router