6.3 KiB
IMPLEMENTATION_PLAN:统一语言设置
前置条件
| 条件 | 状态 |
|---|---|
| 后端 Schema 定义清晰 | ✅ |
| 前端 Model 定义清晰 | ✅ |
AI 运行时使用 ai_language |
✅ |
| 协议文档存在 | ✅ |
实现步骤
Step 1: 更新协议文档
文件: docs/protocols/profile/profile-protocol.md
- 将
interface_language和ai_language合并为language - 更新示例 JSON
Step 2: 后端 Schema
文件: backend/src/schemas/shared/user.py
class PreferenceSettings(BaseModel):
language: str = "zh-CN"
timezone: str = "Asia/Shanghai"
country: str = "US"
@field_validator("language")
@classmethod
def validate_language(cls, value: str) -> str:
if not _BCP47_PATTERN.fullmatch(value):
raise ValueError("language must be a valid BCP-47 tag")
return value
Step 3: 后端 AI 运行时
文件: backend/src/core/agentscope/runtime/runner.py
# 第 268-276 行
language = "zh-CN"
if user_context.settings is not None:
prefs = getattr(user_context.settings, "preferences", None)
if prefs is not None:
language = getattr(prefs, "language", "zh-CN") or "zh-CN"
system_prompt = build_system_prompt(
agent_type=stage_config.agent_type,
language=language,
llm_config=stage_config.llm_config,
tools=None,
now_utc=datetime.now(timezone.utc),
)
Step 4: 后端 Prompt 构建
文件: backend/src/core/agentscope/prompts/system_prompt.py
def _build_output_rules(*, language: str) -> str:
lang_label = _get_language_label(language)
...
def build_system_prompt(
*,
agent_type: AgentType,
language: str,
llm_config: LlmConfig,
tools: list[ToolSchema] | None,
now_utc: datetime,
) -> str:
...
_build_output_rules(language=language),
文件: backend/src/core/agentscope/prompts/worker_rules.py
def get_worker_role_playing(language: str) -> str:
_ = language
...
def get_worker_output_rules(language: str) -> str:
if language.startswith("en"):
...
文件: backend/src/core/agentscope/prompts/agent_prompt.py
def build_agent_prompt(
*,
language: str = "zh-CN",
) -> str:
role_playing = get_worker_role_playing(language)
output_rules = get_worker_output_rules(language)
...
Step 5: 后端测试
文件: backend/tests/unit/test_parse_profile_settings.py
- 字段名
ai_language→language - 字段名
interface_language→language
文件: backend/tests/unit/test_agentscope_prompts.py
- 参数名
ai_language→language
Step 6: 数据库数据更新
直接用 Supabase MCP 执行 SQL(无需迁移脚本):
UPDATE profiles
SET settings = jsonb_set(
settings - 'interface_language' - 'ai_language',
'{preferences,language}',
COALESCE(
settings->'preferences'->>'interface_language',
settings->'preferences'->>'ai_language',
'"zh-CN"'
)::jsonb
)
WHERE settings->'preferences' ?| array['interface_language', 'ai_language'];
Step 7: 前端 Model
文件: apps/lib/features/settings/data/models/profile_settings.dart
class PreferenceSettings {
const PreferenceSettings({
this.language = 'zh-CN',
this.timezone = 'Asia/Shanghai',
this.country = 'US',
});
final String language;
final String timezone;
final String country;
PreferenceSettings copyWith({
String? language,
String? timezone,
String? country,
}) {
return PreferenceSettings(
language: language ?? this.language,
timezone: timezone ?? this.timezone,
country: country ?? this.country,
);
}
}
// 更新 defaultsForLocale
factory ProfileSettingsV1.defaultsForLocale(Locale locale) {
final tag = languageTagFromLocale(locale);
return ProfileSettingsV1(
preferences: PreferenceSettings(language: tag),
);
}
Step 8: 前端 API
文件: apps/lib/features/settings/data/apis/profile_api.dart
// 序列化 (第 45 行)
'language': settings.preferences.language,
// 反序列化 (第 114 行)
language: (preferencesRaw['language'] as String?) ?? 'zh-CN',
Step 9: 前端设置界面
文件: apps/lib/features/settings/presentation/screens/general_settings_screen.dart
移除第 75-95 行的 AI 语言 SettingsMenuTile,修改剩余的语言选项:
SettingsMenuTile(
icon: Icons.language_rounded,
title: l10n.settingsLanguage,
subtitle: displayLanguageLabel(
l10n,
_settings.preferences.language,
),
tint: colors.primary,
background: colors.surfaceContainerHighest,
showDivider: false,
onTap: () => _selectLanguage(
_settings.preferences.language,
(lang) => setState(() {
_settings = _settings.copyWith(
preferences: _settings.preferences.copyWith(
language: lang,
),
);
}),
),
),
Step 10: 前端 i18n
文件: apps/lib/l10n/app_zh.arb
- "settingsInterfaceLanguage": "界面语言",
- "settingsAiLanguage": "AI回复语言",
- "settingsAiLanguageHint": "该字段将对齐..."
+ "settingsLanguage": "语言",
文件: apps/lib/l10n/app_en.arb
- "settingsInterfaceLanguage": "Interface Language",
- "settingsAiLanguage": "AI Response Language",
- "settingsAiLanguageHint": "This field will align..."
+ "settingsLanguage": "Language",
文件: apps/lib/l10n/app_zh_hant.arb
- "settingsInterfaceLanguage": "介面語言",
- "settingsAiLanguage": "AI 回覆語言",
+ "settingsLanguage": "語言",
Step 11: 重新生成 l10n
cd apps && flutter gen-l10n
Step 12: 更新其他协议文档
文件: docs/protocols/divination/divination-run-protocol.md
第 240 行:
- - Language rule: `conclusion`, `focus_points`, `advice`, `keywords`, `answer` should follow user `ai_language` preference unless user explicitly requests otherwise.
+ - Language rule: `conclusion`, `focus_points`, `advice`, `keywords`, `answer` should follow user `language` preference unless user explicitly requests otherwise.
验证
# 后端
cd backend
uv run pytest tests/unit/test_parse_profile_settings.py tests/unit/test_agentscope_prompts.py -v
./infra/scripts/dev-migrate.sh migrate
# 前端
cd apps
flutter gen-l10n
flutter analyze