feat(server): 设置持久化新增 LLM 模型表与主题字段

- SettingsLlmForm 新增 models 列表(SettingsModelRow:slot/provider/url/apiKey/modelId/type),支持多模型行持久化
- settings 服务读写模型表与主题相关字段,更新 test_settings_persistence 测试
This commit is contained in:
caoxiaozhu
2026-06-26 22:41:40 +08:00
parent 43c3ff860c
commit 9c3fa80d22
3 changed files with 164 additions and 11 deletions

View File

@@ -56,6 +56,23 @@ class SettingsSessionForm(BaseModel):
conversationRetentionDays: int = Field(default=3, ge=1, le=10)
class SettingsModelRow(BaseModel):
slot: str = Field(min_length=1, max_length=64)
provider: str = Field(min_length=1, max_length=64)
url: str = Field(min_length=1, max_length=512)
apiKey: str = Field(default="", max_length=1024)
apiKeyConfigured: bool = False
modelId: str = Field(min_length=1, max_length=255)
type: Literal["llm", "embedding", "rerank"] = "llm"
@field_validator("slot", "provider", "url", "apiKey", "modelId", mode="before")
@classmethod
def strip_model_row_string(cls, value: str | None) -> str | None:
if value is None:
return None
return value.strip()
class SettingsLlmForm(BaseModel):
mainProvider: str = Field(min_length=1, max_length=64)
mainModel: str = Field(min_length=1, max_length=255)
@@ -80,6 +97,7 @@ class SettingsLlmForm(BaseModel):
rerankerEndpoint: str = Field(min_length=1, max_length=512)
rerankerApiKey: str = Field(default="", max_length=1024)
rerankerApiKeyConfigured: bool = False
models: list[SettingsModelRow] = Field(default_factory=list)
@field_validator(
"mainProvider",
@@ -201,7 +219,7 @@ class ModelConnectivityTestRequest(BaseModel):
model: str = Field(min_length=1, max_length=255)
api_key: str | None = Field(default=None, max_length=1024)
capability: Literal["chat", "embedding", "reranker"] = "chat"
slot: Literal["main", "backup", "embedding", "reranker"] | None = None
slot: str | None = Field(default=None, max_length=64)
@field_validator("provider", "endpoint", "model", "api_key", mode="before")
@classmethod
@@ -234,7 +252,7 @@ class SettingsCacheClearRead(BaseModel):
class RuntimeModelConfigRead(BaseModel):
slot: Literal["main", "backup", "embedding", "reranker"]
slot: str
provider: str
model: str
endpoint: str