nanobot/nanobot/webui/nanobot_features_api.py
Xubin Ren fe0717b385
feat(webui): add guided setup flows
* feat(channels): add guided setup flows

* test(channels): preserve setup config values

* fix(channels): reflect saved setup state

* refactor(channels): simplify setup state metadata

* fix(channels): harden setup lifecycle

* refactor(channels): centralize setup contracts

* fix(channels): route setup actions through webui shim

* fix(channels): adapt settings for compact screens

* fix(models): preserve default preset display

* feat(models): add curated Codex catalog

* fix(webui): stop attached gateway on interrupt

* fix(webui): simplify apps catalog

* docs(webui): clarify apps and runtime features

* feat(settings): add guided capability setup

* fix(webui): harden setup and managed services

* test: keep managed runtime checks portable

* test: scope POSIX runtime coverage

* fix(webui): simplify file settings

* feat(files): bundle document reading

* fix(webui): harden setup request boundaries

* fix(webui): prevent channel setup status squeeze

* fix(settings): group provider compatibility aliases

* refactor(settings): remove redundant setup surfaces

* fix(webui): harden guided setup lifecycle

* fix(webui): preserve channel setup compatibility
2026-07-13 13:11:46 +08:00

43 lines
1.4 KiB
Python

"""Nanobot optional feature helpers for WebUI Settings."""
from __future__ import annotations
from typing import Any
from nanobot.channels._feishu_instances import DEFAULT_INSTANCE_ID
from nanobot.optional_features import (
OptionalFeatureError,
disable_optional_feature,
enable_optional_feature,
optional_features_payload,
)
from nanobot.webui.http_utils import query_first
QueryParams = dict[str, list[str]]
def nanobot_features_payload() -> dict[str, Any]:
return optional_features_payload()
def nanobot_features_action(
action: str,
query: QueryParams,
*,
allow_install: bool = True,
) -> dict[str, Any]:
name = (query_first(query, "name") or "").strip()
instance_id = (query_first(query, "instance_id") or DEFAULT_INSTANCE_ID).strip()
if not name:
raise OptionalFeatureError("missing feature name")
if action == "enable":
return enable_optional_feature(name, allow_install=allow_install, instance_id=instance_id)
if action == "disable":
if name == "websocket":
raise OptionalFeatureError(
"The WebUI websocket channel cannot be disabled from WebUI. "
"Use `nanobot plugins disable websocket` from a terminal if you need to disable it.",
status=400,
)
return disable_optional_feature(name, instance_id=instance_id)
raise OptionalFeatureError(f"unknown feature action '{action}'", status=404)