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: StargazerService

Stargazer 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 from web and doubles as a lightweight, duck-typed stand-in for the retired BotRunner: 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, and on_stop() tears the server down. Instantiated by main() and injected into the FastAPI app via web.set_bot_runner() so route handlers can reach bot state.

Parameters:
  • cfg (Config)

  • redis_client (Any)

  • instance_id (str)

__init__(cfg, redis_client, instance_id)[source]

Construct the Web service and pre-build its BotRunner-surrogate state.

Initializes the StargazerService base as the "web" service (with a health server) and pre-creates the duck-typed BotRunner API the dashboard expects: adapters (empty here — the real platform adapters live in the Gateway service), a ToolRegistry, and the stop event / uvicorn handles used by run() and on_stop(). Heavy dependencies (KG manager, SWORD, task manager) are deferred to on_start(). Called by main() when launching the service standalone.

Parameters:
  • cfg (Config) – Loaded Config (tool permissions, web host/port, …).

  • redis_client (Any) – Async Redis client shared with the base service.

  • instance_id (str) – Unique id for this process (e.g. "web-ab12cd34").

Return type:

None

get_adapter(platform_name)[source]

Return the platform adapter for platform_name — always None here.

Part of the duck-typed BotRunner surface 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 returns None. 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.

Parameters:

platform_name (str) – Platform identifier such as "discord" or "matrix".

Return type:

Any | None

Returns:

Always None in this surrogate.

async start_platform(platform_name)[source]

Reject a platform-start request from the dashboard.

A deliberate no-op stub on the BotRunner surrogate: 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 in web/bot_admin.py and web/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:

None

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 in web/bot_admin.py and web/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:

None

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 into self.tool_registry via tool_loader.load_tools() (off-thread), constructs the KnowledgeGraphManager, boots the SWORD subsystem via sword.factory.build_sword_system(), and wires a TaskManager. The assembled service is injected as the FastAPI app’s bot_runner surrogate (web.set_bot_runner()) so dashboard routes can reach bot state without booting message processing.

Return type:

None

async run()[source]

Block the service until uvicorn exits or a shutdown is requested.

The service’s main loop, called by the base StargazerService after on_start() (see main(), which awaits service.boot() then service.run()). It races the long-lived self._web_task (the uvicorn serve() task, wrapped in asyncio.shield() so it is not cancelled here) against a waiter on self._stop_event (set by on_stop()); whichever completes first wins, and the still-pending waiter is cancelled. Returns immediately if uvicorn was never started.

Return type:

None

async on_stop()[source]

Gracefully shut the uvicorn web server down.

The service’s teardown hook, invoked by the base StargazerService during shutdown (ultimately triggered by the SIGINT/SIGTERM handlers installed in main()). It sets self._stop_event to release run(), asks the uvicorn server to exit by flipping self.server.should_exit, and waits up to self.shutdown_timeout seconds for the serve task to finish. If uvicorn overruns that budget the task is cancelled and the resulting asyncio.CancelledError is swallowed so shutdown still completes.

Return type:

None

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, constructs WebService, installs SIGINT/SIGTERM handlers that trigger a graceful shutdown(), then boots and runs the service, closing the Redis client on exit. Executed via asyncio.run(main()) when web_main.py is run standalone (the stargazer-web systemd unit).

Return type:

None