feat(settings): remove user agent override
This commit is contained in:
@@ -58,7 +58,7 @@ Open ComfyUI Settings and look for the **Mutiny** section. From there, configure
|
||||
- **Discord Token**: The private account credential Discord uses to identify
|
||||
and authenticate your logged-in session. **This is effecitvely your username and password rolled into one**. Mutiny saves the supplied token into your operating system's secure credential storage.
|
||||
> This project does **not** provide instructions for obtaining your Discord token, and you should read the disclaimer above before deciding whether to use one with Mutiny.
|
||||
- **User Agent** and **API Endpoint**: Optional overrides for advanced cases. You can probably leave these alone.
|
||||
- **API Endpoint**: Optional advanced override. You can probably leave this alone.
|
||||
- **Artifact Cache RAM** and **Artifact Disk**: Control how much context Mutiny keeps around for recognizing earlier Midjourney outputs.
|
||||
- **Task Timeout Minutes**: Controls how long ComfyUI waits before a running job times out.
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ ComfyUI-Mutiny 在正式起航之前需要做一点配置。
|
||||
- **Channel ID**:Mutiny 应该提交任务所使用的 Discord 频道。
|
||||
- **Discord Token**:Discord 用来识别并验证你当前登录会话的私密账户凭据。**这实际上等同于把你的用户名和密码合并成一个值**。Mutiny 会把你提供的 token 保存到操作系统的安全凭据存储中。
|
||||
> 本项目**不会**提供如何获取 Discord token 的说明。在决定是否将 token 与 Mutiny 一起使用之前,请先阅读上面的免责声明。
|
||||
- **User Agent** 和 **API Endpoint**:面向高级场景的可选覆盖项。大多数情况下你可以保持默认。
|
||||
- **API Endpoint**:面向高级场景的可选覆盖项。大多数情况下你可以保持默认。
|
||||
- **Artifact Cache RAM** 和 **Artifact Disk**:控制 Mutiny 为识别先前 Midjourney 输出而保留多少上下文。
|
||||
- **Task Timeout Minutes**:控制 ComfyUI 在运行中的任务超时之前等待多久。
|
||||
|
||||
|
||||
+13
-6
@@ -5,9 +5,6 @@ from __future__ import annotations
|
||||
from dataclasses import asdict, dataclass, field, fields, is_dataclass, replace
|
||||
from typing import Any, Mapping, MutableMapping
|
||||
|
||||
_DEFAULT_USER_AGENT = (
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0"
|
||||
)
|
||||
_DEFAULT_API_ENDPOINT = "https://discord.com/api/v9"
|
||||
|
||||
|
||||
@@ -22,11 +19,10 @@ class SettingsMetadata:
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DiscordSettings:
|
||||
"""Store Discord identifiers and optional transport metadata."""
|
||||
"""Store Discord identifiers and optional API endpoint override."""
|
||||
|
||||
guild_id: str = ""
|
||||
channel_id: str = ""
|
||||
user_agent: str = _DEFAULT_USER_AGENT
|
||||
api_endpoint: str = _DEFAULT_API_ENDPOINT
|
||||
|
||||
|
||||
@@ -64,7 +60,7 @@ class PluginSettings:
|
||||
@classmethod
|
||||
def from_dict(cls, data: Mapping[str, Any] | None) -> "PluginSettings":
|
||||
"""Build a validated settings snapshot from persisted JSON data."""
|
||||
payload = data or {}
|
||||
payload = _drop_removed_settings_keys(data or {})
|
||||
return cls(
|
||||
metadata=_coerce_section(
|
||||
SettingsMetadata, payload.get("metadata"), "metadata"
|
||||
@@ -91,6 +87,17 @@ class PluginSettings:
|
||||
return replace(self, **applied)
|
||||
|
||||
|
||||
def _drop_removed_settings_keys(data: Mapping[str, Any]) -> dict[str, Any]:
|
||||
"""Return persisted settings with known removed keys stripped out."""
|
||||
payload = dict(data)
|
||||
discord = payload.get("discord")
|
||||
if isinstance(discord, Mapping) and "user_agent" in discord:
|
||||
payload["discord"] = {
|
||||
key: value for key, value in discord.items() if key != "user_agent"
|
||||
}
|
||||
return payload
|
||||
|
||||
|
||||
def _coerce_section(section_cls, value: Any, label: str):
|
||||
"""Coerce a persisted section into its dataclass representation."""
|
||||
if value is None:
|
||||
|
||||
+1
-7
@@ -101,7 +101,6 @@ class SettingsService:
|
||||
token_provider=self.create_token_provider(),
|
||||
guild_id=settings.discord.guild_id,
|
||||
channel_id=settings.discord.channel_id,
|
||||
user_agent=settings.discord.user_agent,
|
||||
api_endpoint=settings.discord.api_endpoint,
|
||||
cache=self._build_mutiny_cache_config(settings),
|
||||
execution={
|
||||
@@ -210,7 +209,7 @@ class SettingsService:
|
||||
self._assert_known_keys(
|
||||
section_name,
|
||||
section_value,
|
||||
{"guild_id", "channel_id", "user_agent", "api_endpoint"},
|
||||
{"guild_id", "channel_id", "api_endpoint"},
|
||||
)
|
||||
normalized = {}
|
||||
if "guild_id" in section_value:
|
||||
@@ -221,11 +220,6 @@ class SettingsService:
|
||||
normalized["channel_id"] = self._normalize_string(
|
||||
section_value["channel_id"]
|
||||
)
|
||||
if "user_agent" in section_value:
|
||||
normalized["user_agent"] = self._normalize_optional_string(
|
||||
section_value["user_agent"],
|
||||
default_value=PluginSettings().discord.user_agent,
|
||||
)
|
||||
if "api_endpoint" in section_value:
|
||||
normalized["api_endpoint"] = self._normalize_optional_string(
|
||||
section_value["api_endpoint"],
|
||||
|
||||
@@ -41,7 +41,6 @@ def test_repository_round_trips_settings_snapshot(tmp_path):
|
||||
"api_endpoint": original.discord.api_endpoint,
|
||||
"channel_id": "channel-456",
|
||||
"guild_id": "guild-123",
|
||||
"user_agent": original.discord.user_agent,
|
||||
}
|
||||
|
||||
|
||||
@@ -53,3 +52,39 @@ def test_repository_raises_for_invalid_json(tmp_path):
|
||||
|
||||
with pytest.raises(RuntimeError, match="not valid JSON"):
|
||||
repository.load()
|
||||
|
||||
|
||||
def test_repository_ignores_removed_user_agent_from_existing_settings_file(tmp_path):
|
||||
"""Load older settings files without preserving the removed user-agent override."""
|
||||
settings_path = tmp_path / "mutiny.settings.json"
|
||||
settings_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"metadata": {
|
||||
"schema_version": 1,
|
||||
"migration_completed": True,
|
||||
"migrated_from_legacy": False,
|
||||
},
|
||||
"discord": {
|
||||
"guild_id": "guild-123",
|
||||
"channel_id": "channel-456",
|
||||
"user_agent": "legacy-agent",
|
||||
"api_endpoint": "https://discord.com/api/v9",
|
||||
},
|
||||
"cache": {
|
||||
"artifact_cache_ram_max_mb": 32,
|
||||
"disk_cache_max_mb": 256,
|
||||
},
|
||||
"engine": {"execution": {"task_timeout_minutes": 5}},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
repository = SettingsRepository(settings_path)
|
||||
|
||||
loaded = repository.load()
|
||||
|
||||
assert loaded.discord.guild_id == "guild-123"
|
||||
assert loaded.discord.channel_id == "channel-456"
|
||||
assert loaded.discord.api_endpoint == "https://discord.com/api/v9"
|
||||
assert not hasattr(loaded.discord, "user_agent")
|
||||
|
||||
@@ -215,6 +215,16 @@ def test_service_reports_unknown_settings_sections(tmp_path):
|
||||
service.save_settings({"unknown": {}})
|
||||
|
||||
|
||||
def test_service_rejects_removed_user_agent_override_payloads(tmp_path):
|
||||
"""Reject removed user-agent overrides instead of silently persisting them."""
|
||||
service, _token_store = build_service(tmp_path)
|
||||
|
||||
with pytest.raises(
|
||||
SettingsValidationError, match="Unknown discord keys: user_agent"
|
||||
):
|
||||
service.save_settings({"discord": {"user_agent": "legacy-agent"}})
|
||||
|
||||
|
||||
def test_service_persists_migration_completion_when_no_legacy_files_exist(tmp_path):
|
||||
"""Mark migration complete even when there is nothing to import."""
|
||||
service, _token_store = build_service(tmp_path)
|
||||
|
||||
@@ -15,7 +15,6 @@ def test_settings_ui_uses_native_grouped_mutiny_rows():
|
||||
'id: "Mutiny.Discord.GuildId"',
|
||||
'id: "Mutiny.Discord.ChannelId"',
|
||||
'id: "Mutiny.Discord.DiscordToken"',
|
||||
'id: "Mutiny.Discord.UserAgent"',
|
||||
'id: "Mutiny.Discord.ApiEndpoint"',
|
||||
'id: "Mutiny.Cache.ArtifactCacheRamMaxMb"',
|
||||
'id: "Mutiny.Cache.ArtifactCacheRamHelp"',
|
||||
@@ -172,6 +171,7 @@ def test_settings_ui_uses_native_grouped_mutiny_rows():
|
||||
'id: "Mutiny.General.Actions"',
|
||||
'id: "Mutiny.General.Status"',
|
||||
'id: "Mutiny.Discord.Description"',
|
||||
'id: "Mutiny.Discord.UserAgent"',
|
||||
'id: "Mutiny.Cache.Description"',
|
||||
"sectionDescriptionParts",
|
||||
'"Test Configuration"',
|
||||
|
||||
@@ -200,7 +200,6 @@ function createDefaultSnapshot() {
|
||||
guildId: "",
|
||||
channelId: "",
|
||||
tokenConfigured: false,
|
||||
userAgent: "",
|
||||
apiEndpoint: "",
|
||||
},
|
||||
cache: {
|
||||
@@ -229,7 +228,6 @@ function normalizeSettingsStatus(payload = {}) {
|
||||
guildId: discord.guild_id || "",
|
||||
channelId: discord.channel_id || "",
|
||||
tokenConfigured: Boolean(payload.token_configured),
|
||||
userAgent: discord.user_agent || "",
|
||||
apiEndpoint: discord.api_endpoint || "",
|
||||
},
|
||||
cache: {
|
||||
@@ -1874,17 +1872,6 @@ const TEXT_ROW_DEFINITIONS = [
|
||||
parseValue: (value) => value,
|
||||
buildPayload: (value) => ({ discord: { channel_id: value } }),
|
||||
},
|
||||
{
|
||||
id: "Mutiny.Discord.UserAgent",
|
||||
name: "User Agent",
|
||||
section: "discord",
|
||||
tooltip: "Override the Discord HTTP user agent when needed.",
|
||||
sortOrder: 370,
|
||||
readValue: (snapshot) => snapshot.discord.userAgent,
|
||||
formatValue: (value) => String(value || ""),
|
||||
parseValue: (value) => value,
|
||||
buildPayload: (value) => ({ discord: { user_agent: value } }),
|
||||
},
|
||||
{
|
||||
id: "Mutiny.Discord.ApiEndpoint",
|
||||
name: "API Endpoint",
|
||||
|
||||
Reference in New Issue
Block a user