feat(config): add actionable startup diagnostics and WebUI recovery (#5110)

This commit is contained in:
chengyongru
2026-07-28 18:52:05 +08:00
committed by GitHub
parent 76ab04ac48
commit 0c6c0438d4
19 changed files with 1425 additions and 64 deletions
+19 -6
View File
@@ -1833,12 +1833,10 @@ def _test_provider_snapshot(provider: object, config: Config) -> ProviderSnapsho
def _patch_webui_provider_ready(monkeypatch) -> None:
provider = _fake_provider()
def _snapshot(config: Config, **_kwargs) -> ProviderSnapshot:
return _test_provider_snapshot(provider, config)
monkeypatch.setattr("nanobot.providers.factory.build_provider_snapshot", _snapshot)
monkeypatch.setattr(
"nanobot.providers.factory.validate_provider_setup",
lambda _config: None,
)
def _patch_gateway_ports_free(monkeypatch) -> None:
@@ -1883,6 +1881,10 @@ def _patch_cli_command_runtime(
"nanobot.providers.factory.load_provider_snapshot",
lambda _config_path=None: _test_provider_snapshot(provider_factory(config), config),
)
monkeypatch.setattr(
"nanobot.cli.commands._provider_setup_error",
lambda _config: None,
)
_patch_gateway_ports_free(monkeypatch)
if message_bus is not None:
@@ -2116,6 +2118,9 @@ def test_webui_missing_runtime_env_fails_before_starting_gateway(
assert result.exit_code == 1
assert missing_env in result.stdout
assert "nanobot status --config" in result.stdout
assert config_file.name in result.stdout
assert "Traceback" not in result.stdout
assert f"${{{missing_env}}}" in config_file.read_text(encoding="utf-8")
@@ -2145,6 +2150,10 @@ def test_webui_yes_still_refuses_invalid_custom_model_setup(
assert result.exit_code == 1
assert "provider/model setup is incomplete" in result.stdout
assert "Settings → Models" in result.stdout
assert "nanobot onboard --wizard" in result.stdout
assert "nanobot status --config" in result.stdout
assert config_file.name in result.stdout
def test_webui_background_starts_runtime_and_opens_browser(monkeypatch, tmp_path: Path) -> None:
@@ -2564,6 +2573,7 @@ def test_gateway_unbound_agent_cron_is_skipped(
monkeypatch.setattr("nanobot.config.loader.load_config", lambda _path=None: config)
monkeypatch.setattr("nanobot.cli.commands.sync_workspace_templates", lambda _path: None)
monkeypatch.setattr("nanobot.providers.factory.make_provider", lambda _config: provider)
monkeypatch.setattr("nanobot.cli.commands._provider_setup_error", lambda _config: None)
_patch_gateway_ports_free(monkeypatch)
monkeypatch.setattr(
"nanobot.providers.factory.build_provider_snapshot",
@@ -2691,6 +2701,7 @@ def test_gateway_bound_cron_runs_as_session_turn(
monkeypatch.setattr("nanobot.config.loader.load_config", lambda _path=None: config)
monkeypatch.setattr("nanobot.cli.commands.sync_workspace_templates", lambda _path: None)
monkeypatch.setattr("nanobot.providers.factory.make_provider", lambda _config: provider)
monkeypatch.setattr("nanobot.cli.commands._provider_setup_error", lambda _config: None)
_patch_gateway_ports_free(monkeypatch)
monkeypatch.setattr(
"nanobot.providers.factory.build_provider_snapshot",
@@ -2997,6 +3008,8 @@ def test_gateway_local_trigger_queue_submits_agent_turns(
agent_kwargs = seen["agent_from_config_kwargs"]
kwargs = seen["local_trigger_queue_kwargs"]
assert isinstance(agent_kwargs["provider"], UnconfiguredProvider) is bool(setup_error)
refreshed_snapshot = agent_kwargs["provider_snapshot_loader"]()
assert not isinstance(refreshed_snapshot.provider, UnconfiguredProvider)
assert "local_trigger_store" in agent_kwargs
assert kwargs["store"] is agent_kwargs["local_trigger_store"]
assert "bus" not in kwargs