web_main
Entry point for the Web Dashboard and StarWiki.
Runs the FastAPI web interface and acts as a lightweight surrogate for the legacy BotRunner, providing the state required by the web application without booting monolithic message processing.
- class web_main.WebService(cfg, redis_client, instance_id)[source]
Bases:
StargazerServiceStargazer service that hosts the FastAPI dashboard and StarWiki.
The
"web"microservice in the five-service split (gateway / inference / agents / consolidation / web). It runs the uvicorn-hosted FastAPI app fromweband doubles as a lightweight, duck-typed stand-in for the retiredBotRunner: it exposes the attributes the dashboard routes reach for (adapters,tool_registry,kg_manager,task_manager, …) without booting any message-processing loop. Because the real platform adapters live in the Gateway service, the platform-lifecycle methods here are deliberate no-op stubs.It subclasses
StargazerService, so the base drives its lifecycle:on_start()builds dependencies and starts uvicorn,run()blocks until shutdown, andon_stop()tears the server down. Instantiated bymain()and injected into the FastAPI app viaweb.set_bot_runner()so route handlers can reach bot state.- __init__(cfg, redis_client, instance_id)[source]
Construct the Web service and pre-build its BotRunner-surrogate state.
Initializes the
StargazerServicebase as the"web"service (with a health server) and pre-creates the duck-typedBotRunnerAPI the dashboard expects:adapters(empty here — the real platform adapters live in the Gateway service), aToolRegistry, and the stop event / uvicorn handles used byrun()andon_stop(). Heavy dependencies (KG manager, SWORD, task manager) are deferred toon_start(). Called bymain()when launching the service standalone.
- get_adapter(platform_name)[source]
Return the platform adapter for
platform_name— alwaysNonehere.Part of the duck-typed
BotRunnersurface the dashboard expects. In the distributed architecture the real platform adapters live in the Gateway service, not in the web process, so this surrogate has no adapters to hand out and unconditionally returnsNone. Has no side effects. Dashboard routes that call it (e.g.web/bot_admin.py,web/platforms_api.py,web/deps.py,web/ncm_chart_api.py,web/sillytavern.py) must therefore tolerate a missing adapter when running against the web service.
- async start_platform(platform_name)[source]
Reject a platform-start request from the dashboard.
A deliberate no-op stub on the
BotRunnersurrogate: platform lifecycle is owned by the Gateway service in distributed mode, so the web process cannot start an adapter and instead signals that clearly to the caller. Invoked by the dashboard start/stop controls inweb/bot_admin.pyandweb/platforms_api.py, which should surface the failure to the operator.- Parameters:
platform_name (
str) – Platform the operator asked to start (e.g."discord").- Raises:
NotImplementedError – Always, because platform lifecycle lives in the Gateway service.
- Return type:
- async stop_platform(platform_name)[source]
Reject a platform-stop request from the dashboard.
The stop counterpart to
start_platform(); also a no-op stub because the web process holds no live adapters and platform lifecycle is managed by the Gateway service. Invoked by the dashboard stop controls inweb/bot_admin.pyandweb/platforms_api.py, which should surface the failure to the operator.- Parameters:
platform_name (
str) – Platform the operator asked to stop (e.g."discord").- Raises:
NotImplementedError – Always, because platform lifecycle lives in the Gateway service.
- Return type:
- async on_start()[source]
Build the dashboard’s runtime dependencies and register as bot_runner.
The Web service’s startup phase (invoked by
boot()). Loads tools intoself.tool_registryviatool_loader.load_tools()(off-thread), constructs theKnowledgeGraphManager, boots the SWORD subsystem viasword.factory.build_sword_system(), and wires aTaskManager. The assembled service is injected as the FastAPI app’sbot_runnersurrogate (web.set_bot_runner()) so dashboard routes can reach bot state without booting message processing.- Return type:
- async run()[source]
Block the service until uvicorn exits or a shutdown is requested.
The service’s main loop, called by the base
StargazerServiceafteron_start()(seemain(), which awaitsservice.boot()thenservice.run()). It races the long-livedself._web_task(the uvicornserve()task, wrapped inasyncio.shield()so it is not cancelled here) against a waiter onself._stop_event(set byon_stop()); whichever completes first wins, and the still-pending waiter is cancelled. Returns immediately if uvicorn was never started.- Return type:
- async on_stop()[source]
Gracefully shut the uvicorn web server down.
The service’s teardown hook, invoked by the base
StargazerServiceduring shutdown (ultimately triggered by the SIGINT/SIGTERM handlers installed inmain()). It setsself._stop_eventto releaserun(), asks the uvicorn server to exit by flippingself.server.should_exit, and waits up toself.shutdown_timeoutseconds for the serve task to finish. If uvicorn overruns that budget the task is cancelled and the resultingasyncio.CancelledErroris swallowed so shutdown still completes.- Return type:
- async web_main.main()[source]
Async entry point: build and run the Web service until signalled.
Loads
Config, mints an instance id, opens an async Redis client, constructsWebService, installs SIGINT/SIGTERM handlers that trigger a gracefulshutdown(), then boots and runs the service, closing the Redis client on exit. Executed viaasyncio.run(main())whenweb_main.pyis run standalone (thestargazer-websystemd unit).- Return type: