Skip to content

feat(hsr): 体验整改——直控免导入、修复五个 bug、问题提前到界面 - #569

Merged
qiyinxi merged 11 commits into
AUTO-MAS-Project:devfrom
qiyinxi:feat/hsr-experience-20260905
Sep 5, 2026
Merged

feat(hsr): 体验整改——直控免导入、修复五个 bug、问题提前到界面#569
qiyinxi merged 11 commits into
AUTO-MAS-Project:devfrom
qiyinxi:feat/hsr-experience-20260905

Conversation

@qiyinxi

@qiyinxi qiyinxi commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

HSR 专项一轮体验整改,修掉 5 个 bug、对齐 1 处违反仓库口径的实现、把 4 类「跑完才知道」的问题提前到界面上。

起因是用户反馈 HSR「很不人性化」,外加一份真实运行日志:那次外部脚本其实全部成功,MAS 却把两个模块都记成了失败。

修的 bug

三月七助手跑完自己把游戏关了,本已成功的模块被判失败、下一个模块再空跑一次。
M7A tasks/game/__init__.py:250 只要 after_finish 不是 "None" 就调 shutdown(),而 module/game/base.py:112shutdown() 第一行是无条件 stop_game()after_finish="Exit" 也照杀)。MAS 给 SRA 的临时配置里早就把 missionAccomplished 五个收尾动作全关了,M7A 这边只关了通知、after_finish 全仓没人写过。设成「关机」时 M7A 还会在 60 秒后真的关机。现强制钉成 "None";同时守护循环补 run_task.done() 复查(原来 sleep(1) 醒来直接查进程,必然踩中「先关游戏再退出」的窗口),并让「游戏已退出」中止该用户剩余模块而不是接着空跑。

差分宇宙 / 货币战争在日志未确认完成时仍被记成「完成」。
两个 on_success 只在未完成时记 incomplete,随后 AutoProxy 的兜底又无条件补一条 completed,而 record_module_result 是后写入为准。结果:通知里写「完成」,用户页周常标签停在「未完成」,下次运行重复跑。改法照抄历战余响那套已经正确的范式。

体力「补充方式」的选项与 SRA 实际含义错位一格。
SRA TrailblazePowerTask.replenish() 实际是 0=后备开拓力 / 1=燃料 / 2=星琼,MAS 写成 0=燃料 / 1=星琼——选「燃料」实际用的是后备开拓力,而星琼根本选不到。顺带补上缺失的货币战争「刷开局」模式(cw_mode==2)。

外部脚本升级后,单个失效的配置项会让该引擎全部任务表单一起消失、运行时任务直接失败。
Managed.Options 里只要有一个键在原生配置中不存在或类型不符就整体抛错,api.py 的兜底把该引擎四个模块的表单一起丢掉,UI 上还没有清理入口。改为逐项忽略并在界面上列出、可一键清除。

英文与日文界面的三处术语错误。
edit.divergentUniverse 这个 key 承载的其实是「历战余响」,中文日文都对,只有英文照 key 名翻成了 Divergent Universe——而差分宇宙在同一个页面上真实存在,英文用户会看到两个同名却不同的东西(SRC 专项也有同一处错标)。另外「体力配置」的英文与日文沿用了明日方舟的 Sanity/理性,星铁该是开拓力;「侵蚀隧洞」英文名复数有误。

调度台日志每行的时间戳硬编码东八区。
全仓只有 HSR 这么干(MaaFW 用 datetime.now().astimezone()),非中国时区用户看到的每一行都和本机时钟对不上。周常重置日等游戏内日期判定仍按游戏服务器时区,历史日志文件名的 UTC+4 是全仓「游戏日」分桶约定,都不变。

对齐仓库口径

脚本直控不再要求先导入配置快照。
SKILL.md:91 定义直控=直接使用脚本原有配置、由原生 GUI 维护,adapter-code-norms.md:64 明写「直控不得为了字段齐全复制脚本全量配置」。general / Okww / BetterGI 都照此实现,只有 HSR 要求先导入整份快照才肯跑,且快照冻结在导入那一刻、之后脚本里的改动不跟进、UI 上也没有过期提示。技术上并不需要:SRA 的 --inline run 本来就接任意 config 路径,M7A 直接以安装根目录启动即可。

现在直控零配置可跑;「固定为快照」降级成可选覆盖,只服务同一脚本挂多个游戏账号、各跑一套配置的场景,并可一键改回使用脚本当前配置。examples-hsr.md / script-frontend-architectures.md 里给旧语义背书的描述一并改掉。

提前到界面上

  • 切换执行引擎会换掉整套原生配置项和体力副本(各引擎各存一份),控件旁明确说明;当前引擎下没选副本时用户页直接提示,不再等跑完才在日志里体现。
  • 执行引擎因缺少路径被自动改派(原本是静默的第四级回落),现在写进运行日志与两处能力提示。
  • 托管任务的「一键从源配置导入」实际行为是清空用户在 MAS 里的全部覆盖值,改名为「重置为源配置」并加二次确认——原来的名字和成功提示都在说反话,而直控区还有个同名按钮才是真导入。
  • 托管配置项补齐中文名称、取值范围与填写说明(货币战争刷开局那四个重开条件的格式取自 SRA 源码);三月七助手缺少配置说明文件时明确提示,不再显示一堆原始键名。

新增

SRA 配置档案可选。 SRA 把设置存成 %APPDATA%\SRA\configs 下的多份档案,MAS 原先写死取 Default.json(没有则取文件名排序第一份),用户无法选。这份档案决定托管表单显示什么、直控按哪份运行、固定快照抄哪份。选中的档案被删或改名时退回自动模式并在脚本页、用户页、端点响应与运行日志四处提示,不闷声换掉。

本地验证

后端  pytest tests            482 passed, 3 skipped, 97 subtests passed
      pytest tests --collect-only   485 collected,退出码 0
      ruff check app/task/HSR       All checks passed
前端  yarn typecheck / lint         退出码 0
      yarn test                     39 files / 379 tests passed

功能边界与 bug 边界测试按 tests/AGENTS.md 只在本地跑、不提交,共 4 个文件(直控活配置 20 例、失效覆盖丢弃 9 例、SRA 档案选择 8 例、M7A 收尾与守护循环 13 例,另有周常覆盖 9 例与预检 12 例)。周常那条做过反向验证:把补丁 revert 掉重跑,4 条用例变红。

frontend/src/api 是真跑生成器重新生成的,只有 9 个文件因本次 schema 改动而变。其中 Service.ts 带了 3 行 BackendHealth 注释更新,是 dev 基线上生成物本身陈旧所致,不手改生成文件就无法拆掉。

没验证的部分与已知边界

没有真机跑过 SRA / 三月七助手与游戏,直控的活配置与快照两条路、脚本页新下拉的实际渲染、以及用户日志里那段时序,都只有静态检查与单测覆盖。

三月七助手支持用环境变量 MARCH7TH_AFTER_FINISH 覆盖 config.yaml(module/config/config.py:17)。用户如果在系统环境里设了它,本次钉死的 "None" 不生效。概率极小,没有处理。

「游戏进程已退出」会中止该用户当前阶段的剩余模块;但如果外部脚本在游戏被关后自己先以失败退出,仍会继续启动下一个模块——这是基线既有行为,本次没有覆盖。

🤖 Generated with Claude Code

qiyinxi and others added 10 commits September 5, 2026 16:59
口径依据:`.agents/skills/mas-script-specialized-adapter/SKILL.md` 把直控定义为
「直接使用脚本原有配置、由原生 GUI 维护、不回写 MAS 独立配置」,
`references/adapter-code-norms.md` 明确「直控不得为了字段齐全复制脚本全量配置」。
general / Okww / BetterGI 都照此实现,只有 HSR 从早期插件版原样迁来一条
「未导入快照则整个任务预检失败」的硬拦(ad2a4541,无正文、无注释论证),
且快照冻结在导入那一刻,用户之后在 SRA / 三月七助手里的改动 MAS 不跟进。

改法:
- native_control:`Direct.{engine}Config` 为空时走活配置——SRA 把
  `--inline run` 直接指向 `resolve_sra_profile` 解析出的真实 profile,M7A 以真实
  安装根目录启动 `main`;不建临时目录、不复制文件。有快照时隔离目录行为不变。
  两条路日志文案分开,活配置写出实际文件路径。两个 provider 新增
  `native_config_path()` 统一原生配置文件定位;`inspect()` 的 `import_ready`
  保留原义(原生文件存在即可固定为快照),`direct_run_ready` 新增要求原生
  配置文件存在(活配置模式下必须有它)。
- manager.check:删掉「尚未导入快照」硬拦;没有快照时改为校验活的原生配置
  文件存在,缺失时给出「请先在脚本中保存一次设置,或为该用户导入配置快照」
  的明确提示。脚本路径 / 可执行文件的三道既有检查保留。
- api:新增 `clear_direct_config` 与 `POST /api/scripts/hsr/direct-config/clear`,
  与导入端点对称,复用既有 `HSRDirectConfigImportIn/Out` 模型,不改任何
  schema 字段形状;只清空 `Direct` 三个字段,不碰外部文件,不需要路径锁。
- 前端 DirectControlSection:默认态改为「使用脚本当前配置(推荐)」的正常态
  文案与成功色;导入按钮改为「固定当前配置为快照(可选)」;有快照时显示
  固定时间与来源、提示不跟随后续改动,并提供「改回使用脚本当前配置」;
  删掉「已启用的脚本必须先导入用户快照」警告。HSRUserEdit 补对称的清除处理,
  三份词表同步增删。
- 文档:examples-hsr.md / script-frontend-architectures.md 改为新语义,不再给
  「直控=加密快照」背书。
- res/version.json 增加对应「程序优化」条目。

本地验证(tree venv、--basetemp):pytest tests 474 passed 3 skipped;
--collect-only 退出码 0;前端 typecheck / lint / test 全绿。功能边界测试
tests/task/test_hsr_direct_live_config.py 按 tests/AGENTS.md 只留本地不提交。
真机拉起 SRA / 三月七助手的直控路径未在本次验证,只做了静态与单测。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
根因:`_on_sra_weekly_success` / `_on_m7a_weekly_success` 只在日志判定
未完成时记 `incomplete`,判定完成时只登记 Data 写回而不记 module result;
随后 `_run_queue_items` 成功分支的兜底对所有不在排除名单里的模块再记一次
`completed`,而 `HSRRuntimeState.record_module_result` 以后写入为准,
于是 `incomplete` 被覆盖成 `completed`。用户看到的是统计通知写「完成」、
用户页周常标签停在「未完成」、下次运行又重跑一遍。

改法照抄历战余响 `_queue_eow_completion_if_confirmed` 的范式,两步缺一不可:

1. 两个 on_success 的完成分支在 `queue_weekly_completion` 之前显式记
   `completed`,reason 沿用 `detect_weekly_completion` 的返回值。
2. `_run_queue_items` 的兜底排除名单加入 `DivergentUniverse` /
   `CurrencyWars`:这几项的最终结果由 on_success 按日志判定并记满两条分支,
   兜底再记一次会把「未完成」覆盖成「完成」。

不改 `detect_weekly_completion` 判定、重试策略、Data 写回时机与
`record_module_result` 的后写入为准语义。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
问题一:MAS 管控区顶部的「一键从源配置导入」实际行为是把用户在 MAS 里改过的
全部 Managed.Options 覆盖值清空后重新读原生配置,没有二次确认,成功提示还写成
「已导入」,与直控卡片上真正做导入的同名按钮相互混淆。现改名为「重置为源配置」,
补充副文案说明会清除哪些东西,加 a-popconfirm 二次确认,成功提示改为与真实行为
一致;三份词表同步替换旧 key。

问题二:resolve_sra_managed_options / resolve_managed_options 遇到 Managed.Options
里原生配置已不存在的键或类型不符的值时整体 raise ValueError,api.py 的兜底 except
把该引擎四个模块的表单一起丢掉,运行期 _apply_managed_options / _apply_managed_patch
再次抛错让任务直接失败;用户升级 SRA / 三月七助手或换 profile 后只要一个键对不上
就会撞到,且界面没有任何清理入口。现新增 managed_overlay.overlay_managed_options
统一两个引擎的叠加逻辑:对不上的键逐个丢弃、用原生值兜底,丢弃记录以
DroppedOverride 返回;表单发现侧把它编成 JSON 字串放进 HSRManagedModule.warnings
(沿用现有 HSRManagedForm.warnings: list[str] 通道,不改响应模型),运行侧在
MAS 日志里 warning 说明忽略了哪些覆盖。前端 parseHSRDroppedOverrides 还原后在
模块列表打标、在详情面板列出键与原因,并提供带确认的「清除无效覆盖」,只从
Managed.Options 剔掉失效键后保存。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
体验审计里三个「用户被蒙在鼓里」的问题:

一、托管表单字段退化成裸控件
- managed_config.py:_SRA_LABELS 按真实 SRA Default.json(version 4)的键集合
  补齐,连被过滤的 enabled/tasklist/redeemCodes 也给了名称;新增 _SRA_DESCRIPTIONS,
  货币战争刷开局四个重开条件、策略文件/序号、培养目标、补充次数等按 SRA 源码
  (CosmicStrifeTask / RerollStart / TrailblazePowerTask)写清分隔符与前缀含义,
  拿不准的指回 SRA 内同名设置;新增 _SRA_RANGES 给次数、序号、活动关卡序号
  非负下界,不设没有依据的上界。
- 按 SRA 源码修正下拉:replenish.way 0/1/2 = 后备开拓力/燃料/星琼(原表 0 燃料
  1 星琼与源码不符),currencyWars.mode 增加 2 = 刷开局。
- M7A:config.example.yaml 缺失时把原因写进模块级 warnings,前端在表单上方展示;
  borrow_scroll_times / power_limit 补非负下界。

二、切引擎换掉整套配置却一声不吭
- ManagedTaskSection.vue:引擎切换控件下加说明(配置项按引擎分别保存、不带过去
  但保留);展示表单级 warnings。
- StageConfigSection.vue:新格式下当前引擎名下没有主关卡、而另一引擎名下有副本
  时提示重新选择(旧格式的不匹配仍由 nativeEngineMismatch 负责)。
- manager.check():新增 _precheck_daily_stages,口径与 AutoProxy
  _resolve_daily_runnable_parts 完全一致:培养目标/活动双倍已开则不拦;只有该引擎下
  主关卡和历战余响关卡都没有(体力模块无论哪天都会整个跳过)才返回错误;
  「今日不需历战余响」「历战余响到期但未配关卡」两类只写运行日志不阻断。
  判定拆成 stage_runtime.resolve_configured_daily_stages 与
  AutoProxy.resolve_daily_native_modes 两个纯函数,AutoProxy 与 check() 共用。

三、引擎第四级回落静默发生
- task_mapping.py:新增 resolve_script_assignment 返回 HSRScriptAssignment
  (requested / script / fallback),describe_script_fallback 生成提示语;
  get_assigned_script 变成兼容包装,签名与返回不变。
- check() 与 AutoProxy._build_phase_items 把回落写进运行日志;
  api.build_capabilities(脚本级)与 build_managed_config(用户级)把回落写进
  warnings,编辑页顶部与托管区都能看到。

其他:既有公共测试 test_hsr_engine_fallback / test_hsr_account_switch_gate 的
用户夹具补上按引擎分桶的主关卡,让新增预检放行;三份词表新增
edit.hsrEngineSwitchHint / edit.hsrStageMissingForEngine;res/version.json 补两条。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
上一提交把「所指派引擎下既没有体力主关卡也没有历战余响关卡」做成了 check()
的硬拦。但 `TaskSwitch.Daily` 后端默认为 True(app/models/config.py),新建
用户在配好副本之前天然处于这个状态,于是「给第二个号建了用户还没配完」会让
同一脚本下已经配好的其他用户一起跑不了——这正是本轮要消除的那类体验问题。

改为只在任务开始前写一条说明日志。「提前知道」这件事由编辑页那条
「当前引擎下未选择副本」的提示承担,开跑前再复述一次即可,不必把影响面
扩大到整个任务。原先为通过该硬拦而给两份既有公共测试补的关卡夹具一并还原。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SRA 配置档案可选
- HSRConfig 新增 Info.SRAProfile(空串=自动),SRAProfileValidator 只放行能直接
  拼成文件名的档案 id。
- resolve_sra_profile 尊重该配置:档案存在则用它;配了但不存在回退到原有的
  Default → 文件名排序首个逻辑;签名与 (id, path) 返回形状不变。新增
  resolve_sra_profile_selection 返回带 fallback / fallback_reason 的完整结果,
  能力快照与托管配置的 warnings、运行前检查日志、档案列表端点都据此把回退
  说给用户。
- 新增 GET /api/scripts/hsr/sra-profiles 列出 %APPDATA%/SRA/configs 下的档案,
  标出配置值、自动模式会选的档案、实际生效档案与是否回退。
- 脚本编辑页 SRA 路径下方新增「SRA 配置档案」下拉,未配 SRA 路径 / 目录不可读
  时禁用并说明原因,配置的档案已不存在时显示回退提示。

失效覆盖记录结构化
- HSRManagedForm 新增 dropped_overrides(key / reason / value / message),
  warnings 恢复为纯人类可读提示;HSRManagedModule.asdict() 同步输出,
  DroppedOverride.as_warning() 的 JSON 字串编码移除。
- 前端删掉 parseHSRDroppedOverrides,改为读类型化字段的 getHSRDroppedOverrides,
  ManagedTaskSection 展示与「清除无效覆盖」行为不变。

OpenAPI 客户端按本分支后端重新生成(frontend/src/api):新增
HSRManagedDroppedOverride / HSRSRAProfile / HSRSRAProfilesData / HSRSRAProfilesOut
四个模型,HSRConfig_Info、HSRManagedForm、index.ts、HsrService.ts(含本分支此前
未生成的 direct-config/clear)、Service.ts 跟随变化;其余仅换行差异的生成文件
已还原。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`yarn format` 会把 dev 基线上未格式化的 BetterGI 词条一并换行重排。按仓库
规矩,无关格式化改动不得混入修复,这里把三份词表中 61 条「值未变、只是排版
被改」的条目还原成基线写法,只保留本次真正新增或改写的 key。
`HSRAutoProxyTask._append_log` 与 `HSRManager._append_log` 都用
`datetime.now(tz=UTC8)` 打时间戳。全仓只有 HSR 这么做——MaaFW 用
`datetime.now().astimezone()`,通知用 `datetime.now()`——所以非中国时区的
用户看到的 HSR 日志每一行都和自己的墙上时钟对不上(UTC+2 用户差 6 小时)。

改为跟随本机时区。周常重置日、历战余响开始日那几处 `datetime.now(tz=UTC8)`
是游戏服务器日期语义,保持不变;`manager.py` 因此不再需要 UTC8,同步收掉
未使用的导入。历史日志文件名用的 UTC+4 是全仓「游戏日」分桶约定
(MAA / M9A / BetterGI / general / MaaEnd 一致),本次不动。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
真实日志:M7A 体力模块全部成功,MAS 却把它和紧随其后的「日常与奖励」都记成失败。
三个独立缺陷叠在一起:

1. M7A 的 after_finish 没被托管。M7A stop() 在释放 OCR 后,只要 after_finish 不是
   字符串 "None" 就走 shutdown(),而 shutdown() 第一步无条件 stop_game()。MAS 给
   SRA 写临时配置时把 missionAccomplished 五个收尾动作全关,M7A 这边的强制 patch
   只关了 notify_*,after_finish 全仓没写过;用户设成 Shutdown 且未开游戏管理时
   还会连整机一起关。现在新增 M7A_FINISH_ACTION_DISABLE_PATCH 把 after_finish 钉成
   "None"(字面值取自 assets/config/config.example.yaml),并入 write_m7a_patch 的
   patch 与白名单并集,覆盖 Daily / ReceiveRewards / DivergentUniverse / CurrencyWars
   全部托管路径;脚本直控(M7ADirectControlSession)不经过该函数,保持原样跑用户配置。

2. 守护循环 TOCTOU。_run_item_with_game_guard 在 sleep(1) 醒来后没有复查
   run_task.done() 就去看游戏进程;M7A 收尾顺序是先关游戏再自己退出,这个窗口必然
   被踩中,一个已经成功完成的任务被 cancel() 并判失败。现在睡醒后先复查 done(),
   已完成直接跳出走正常返回。

3. 游戏已退出仍继续启动下一模块。_run_queue_items 的 HSRRetryableTaskError 分支只
   对 StartGame 中止剩余模块,其余一律 continue,于是又去跑「日常与奖励」再失败一次。
   新增 HSRGameExitedError(继承 HSRRetryableTaskError,补跑语义不变)由守护循环抛出,
   队列按类型识别并中止该用户当前阶段剩余模块;_remaining_items_after 的未执行原因
   参数化,游戏退出写「游戏进程已退出,当前阶段剩余模块未执行」,不再沿用
   「SRA 登录/切号失败」。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
「失效覆盖记录改为结构化字段」是内部实现,用户感知不到;对应的用户可见
现象已由「单个失效覆盖项不再让整个引擎表单消失、可一键清理」那条覆盖。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @qiyinxi, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 17 hours and 49 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

审查者指南

此 PR 全面修订了 HSR 配置和执行行为:直接控制现在默认使用实时原生脚本设置,并支持可选快照和可选择的 SRA 配置档案;过时的托管覆盖值会安全降级,并在 UI 中进行清理;执行生命周期和结果处理得到修正;引擎回退、缺失阶段和配置问题会在运行前或运行期间报告。

HSR 直接控制使用实时配置或快照的时序图

sequenceDiagram
    participant User
    participant MAS as HSRManager
    participant Provider as NativeControlProvider
    participant Script as SRA_or_M7A
    participant API as HSR_API

    User->>MAS: Enable direct control
    MAS->>Provider: has_user_direct_snapshot()
    alt Snapshot exists
        MAS->>Provider: open_direct_session(snapshot)
        Provider->>Provider: Create isolated runtime config
        Provider->>Script: Run pinned snapshot
    else No snapshot
        MAS->>Provider: open_direct_session(empty_config)
        Provider->>Provider: Resolve native_config_path()
        Provider->>Script: Run current native configuration
    end
    Script-->>MAS: Runtime result
    MAS-->>User: Log execution source and result

    opt User changes source
        User->>API: clear_direct_config()
        API->>MAS: Remove Direct engine snapshot metadata
        MAS-->>User: Direct control uses live configuration
    end
Loading

HSR 受保护的模块执行和游戏退出处理时序图

sequenceDiagram
    participant MAS as HSRAutoProxyTask
    participant Script as ExternalScript
    participant Game
    participant Queue as ModuleQueue
    participant Result as ResultRecorder

    MAS->>Script: run_task()
    loop Guarded execution
        MAS->>MAS: run_task.done()
        alt Script completed
            MAS->>Script: Await result
        else Game process exited
            MAS->>Game: is_process_running()
            MAS->>Script: Cancel running task
            MAS->>Queue: Mark remaining items skipped
            Queue-->>MAS: HSRGameExitedError
        end
    end
    alt Game exit error
        MAS->>Result: record skipped remaining modules
        MAS-->>Queue: Stop current phase
    else Successful result
        MAS->>Result: record_module_result()
    end
Loading

HSR 托管配置覆盖和过时覆盖清理流程图

flowchart TD
    A[Load native SRA or M7A configuration] --> B[Read Managed.Options overrides]
    B --> C{Each override matches native field and type?}
    C -->|Yes| D[Apply override]
    C -->|No| E[Create DroppedOverride record]
    E --> F[Use native value]
    D --> G[Build managed form]
    F --> G
    G --> H[Show stale override warning in UI]
    H --> I{User chooses cleanup?}
    I -->|No| J[Ignore stale override at runtime]
    I -->|Yes| K[Clear selected Managed.Options keys]
    K --> L[Reload managed configuration]
Loading

文件级变更

变更 详情 文件
使 HSR 直接控制与实时原生配置保持一致,同时保留可选的用户级快照,并添加 SRA 配置档案选择功能。
  • 允许使用当前 M7A/SRA 配置进行零配置直接运行。
  • 将导入的快照视为可选覆盖值,并提供清除/重置操作。
  • 添加经过验证的 SRA 配置档案发现、选择和回退报告功能,以及生成的 API 类型和客户端方法。
  • 更新文档和本地化 UI 文案,以说明修订后的语义。
.agents/skills/mas-script-specialized-adapter/references/examples-hsr.md
.agents/skills/mas-script-specialized-adapter/references/script-frontend-architectures.md
app/api/scripts.py
app/models/config.py
app/models/schema.py
app/task/HSR/manager.py
app/task/HSR/tools/api.py
app/task/HSR/tools/native_control.py
app/task/HSR/tools/sra_runtime.py
frontend/src/api/index.ts
frontend/src/api/models/HSRConfig_Info.ts
frontend/src/api/models/HSRSRAProfile.ts
frontend/src/api/models/HSRSRAProfilesData.ts
frontend/src/api/models/HSRSRAProfilesOut.ts
frontend/src/api/services/HsrService.ts
frontend/src/api/services/Service.ts
frontend/src/composables/useHSRPluginApi.ts
frontend/src/views/EditView/Script/HSRScriptEdit.vue
frontend/src/views/EditView/User/HSRUserEdit/DirectControlSection.vue
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts
强化 HSR 执行生命周期和结果统计,避免误报失败、重复运行和错误的完成状态。
  • 强制将 M7A 托管完成行为设为 None,防止脚本意外关闭游戏或主机。
  • 在保护循环唤醒后重新检查外部任务完成状态,并明确区分游戏退出。
  • 在登录失败或游戏退出时中止队列中的剩余项目,并记录明确的跳过原因。
  • 阻止 AutoProxy 覆盖 Divergent Universe 和 Currency Wars 的未完成结果;保留成功完成时的结果。
  • 添加共享的每日阶段和原生模式解析逻辑,确保预检查与运行时行为一致。
  • 使用本地时区记录逐行调度器和运行时日志的时间戳,同时保留游戏日期的时区语义。
app/task/HSR/AutoProxy.py
app/task/HSR/manager.py
app/task/HSR/tools/m7a_config.py
app/task/HSR/tools/m7a_control.py
app/task/HSR/tools/run_model.py
app/task/HSR/tools/sra_control.py
app/task/HSR/tools/stage_runtime.py
使托管配置能够适应过时的覆盖值,并在 UI 中提供可操作的诊断信息。
  • 按字段应用覆盖值;丢弃未知值或类型不兼容的值,而不是导致整个引擎表单失败。
  • 返回被丢弃覆盖值的元数据,并在回退到原生设置时记录被忽略的值。
  • 添加一键移除过时覆盖值的功能,并重命名具有破坏性的来源重置操作,同时增加确认步骤。
  • 添加 M7A 文档缺失警告,以及 SRA 标签、范围、描述、修正后的补充选项和 Currency Wars 重抽模式。
app/models/schema.py
app/task/HSR/tools/managed_overlay.py
app/task/HSR/tools/m7a_config.py
app/task/HSR/tools/managed_config.py
app/task/HSR/tools/sra_runtime.py
frontend/src/composables/useHSRPluginApi.ts
frontend/src/composables/useHSRPluginApi.test.ts
frontend/src/views/EditView/User/HSRUserEdit.vue
frontend/src/views/EditView/User/HSRUserEdit/ManagedTaskSection.vue
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts
在执行前展示之前隐含的 HSR 执行决策和特定引擎的配置状态。
  • 在能力信息、检查结果和运行时日志中报告因路径缺失导致的引擎回退。
  • 当所选引擎没有配置阶段时发出警告,并明确说明阶段和原生选项按引擎分别存储。
  • 在脚本和用户界面中展示 M7A 文档缺失以及 SRA 配置档案回退条件。
  • 针对架构和端点变更重新生成前端 API 模型和服务。
app/task/HSR/AutoProxy.py
app/task/HSR/manager.py
app/task/HSR/task_mapping.py
app/task/HSR/tools/api.py
frontend/src/views/EditView/User/HSRUserEdit/StageConfigSection.vue
frontend/src/views/EditView/User/HSRUserEdit/ManagedTaskSection.vue
frontend/src/views/EditView/Script/HSRScriptEdit.vue
frontend/src/api/models/HSRManagedDroppedOverride.ts
frontend/src/api/models/HSRSRAProfilesData.ts
frontend/src/api/services/HsrService.ts
frontend/src/api/services/Service.ts
修正 HSR 托管字段语义以及面向用户的 SRA 任务配置术语。
  • 按照 SRA 定义的顺序,将开拓力补充值映射为备用电力、燃料和星琼。
  • 添加 Currency Wars刷开局模式,并记录其四种重抽条件格式。
  • 添加本地化标签、描述、验证范围、引擎描述、快照/实时配置术语以及重置确认信息。
app/task/HSR/tools/managed_config.py
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以回复审查评论并输入 @sourcery-ai issue,以根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以随时重新生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中你希望插入摘要的位置写入 @sourcery-ai summary,即可随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以随时重新生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论并且不想再看到它们,此功能会很有用。
  • 忽略所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从新的审查开始,这个功能尤其有用——别忘了评论 @sourcery-ai review 来触发新的审查!

自定义你的使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

This PR comprehensively revises HSR configuration and execution behavior: direct control now defaults to live native script settings with optional snapshots and selectable SRA profiles, stale managed overrides degrade safely with UI cleanup, execution lifecycle/result handling is corrected, and engine fallbacks, missing stages, and configuration issues are reported before or during runs.

Sequence diagram for HSR direct control with live configuration or snapshot

sequenceDiagram
    participant User
    participant MAS as HSRManager
    participant Provider as NativeControlProvider
    participant Script as SRA_or_M7A
    participant API as HSR_API

    User->>MAS: Enable direct control
    MAS->>Provider: has_user_direct_snapshot()
    alt Snapshot exists
        MAS->>Provider: open_direct_session(snapshot)
        Provider->>Provider: Create isolated runtime config
        Provider->>Script: Run pinned snapshot
    else No snapshot
        MAS->>Provider: open_direct_session(empty_config)
        Provider->>Provider: Resolve native_config_path()
        Provider->>Script: Run current native configuration
    end
    Script-->>MAS: Runtime result
    MAS-->>User: Log execution source and result

    opt User changes source
        User->>API: clear_direct_config()
        API->>MAS: Remove Direct engine snapshot metadata
        MAS-->>User: Direct control uses live configuration
    end
Loading

Sequence diagram for HSR guarded module execution and game exit handling

sequenceDiagram
    participant MAS as HSRAutoProxyTask
    participant Script as ExternalScript
    participant Game
    participant Queue as ModuleQueue
    participant Result as ResultRecorder

    MAS->>Script: run_task()
    loop Guarded execution
        MAS->>MAS: run_task.done()
        alt Script completed
            MAS->>Script: Await result
        else Game process exited
            MAS->>Game: is_process_running()
            MAS->>Script: Cancel running task
            MAS->>Queue: Mark remaining items skipped
            Queue-->>MAS: HSRGameExitedError
        end
    end
    alt Game exit error
        MAS->>Result: record skipped remaining modules
        MAS-->>Queue: Stop current phase
    else Successful result
        MAS->>Result: record_module_result()
    end
Loading

Flow diagram for HSR managed configuration overlay and stale override cleanup

flowchart TD
    A[Load native SRA or M7A configuration] --> B[Read Managed.Options overrides]
    B --> C{Each override matches native field and type?}
    C -->|Yes| D[Apply override]
    C -->|No| E[Create DroppedOverride record]
    E --> F[Use native value]
    D --> G[Build managed form]
    F --> G
    G --> H[Show stale override warning in UI]
    H --> I{User chooses cleanup?}
    I -->|No| J[Ignore stale override at runtime]
    I -->|Yes| K[Clear selected Managed.Options keys]
    K --> L[Reload managed configuration]
Loading

File-Level Changes

Change Details Files
Align HSR direct control with live native configurations while retaining optional per-user snapshots and adding SRA profile selection.
  • Allow zero-configuration direct runs from the current M7A/SRA configuration.
  • Treat imported snapshots as optional overrides with clear/reset operations.
  • Add validated SRA profile discovery, selection, fallback reporting, and generated API types/client methods.
  • Update documentation and localized UI copy to describe the revised semantics.
.agents/skills/mas-script-specialized-adapter/references/examples-hsr.md
.agents/skills/mas-script-specialized-adapter/references/script-frontend-architectures.md
app/api/scripts.py
app/models/config.py
app/models/schema.py
app/task/HSR/manager.py
app/task/HSR/tools/api.py
app/task/HSR/tools/native_control.py
app/task/HSR/tools/sra_runtime.py
frontend/src/api/index.ts
frontend/src/api/models/HSRConfig_Info.ts
frontend/src/api/models/HSRSRAProfile.ts
frontend/src/api/models/HSRSRAProfilesData.ts
frontend/src/api/models/HSRSRAProfilesOut.ts
frontend/src/api/services/HsrService.ts
frontend/src/api/services/Service.ts
frontend/src/composables/useHSRPluginApi.ts
frontend/src/views/EditView/Script/HSRScriptEdit.vue
frontend/src/views/EditView/User/HSRUserEdit/DirectControlSection.vue
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts
Harden HSR execution lifecycle and result accounting to prevent false failures, duplicate runs, and incorrect completion statuses.
  • Force M7A managed completion behavior to None so the script cannot shut down the game or host unexpectedly.
  • Recheck external task completion after guard-loop wakeups and classify game exits distinctly.
  • Abort remaining queue items when login fails or the game exits, recording explicit skipped reasons.
  • Stop AutoProxy from overwriting incomplete results for Divergent Universe and Currency Wars; preserve on-success outcomes.
  • Add shared daily-stage and native-mode resolution to keep prechecks and runtime behavior consistent.
  • Use the local timezone for per-line scheduler and runtime log timestamps while preserving game-date timezone semantics.
app/task/HSR/AutoProxy.py
app/task/HSR/manager.py
app/task/HSR/tools/m7a_config.py
app/task/HSR/tools/m7a_control.py
app/task/HSR/tools/run_model.py
app/task/HSR/tools/sra_control.py
app/task/HSR/tools/stage_runtime.py
Make managed configuration resilient to stale overrides and expose actionable diagnostics in the UI.
  • Overlay overrides per field and discard unknown or type-incompatible values instead of failing the entire engine form.
  • Return dropped-override metadata and log ignored values while falling back to native settings.
  • Add one-click removal for stale overrides and rename the destructive source reset action with confirmation.
  • Add M7A missing-documentation warnings plus SRA labels, ranges, descriptions, corrected replenish options, and Currency Wars reroll mode.
app/models/schema.py
app/task/HSR/tools/managed_overlay.py
app/task/HSR/tools/m7a_config.py
app/task/HSR/tools/managed_config.py
app/task/HSR/tools/sra_runtime.py
frontend/src/composables/useHSRPluginApi.ts
frontend/src/composables/useHSRPluginApi.test.ts
frontend/src/views/EditView/User/HSRUserEdit.vue
frontend/src/views/EditView/User/HSRUserEdit/ManagedTaskSection.vue
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts
Surface previously implicit HSR execution decisions and engine-specific configuration state before execution.
  • Report engine fallback caused by missing paths in capabilities, checks, and runtime logs.
  • Warn when the selected engine lacks configured stages and clarify that stages and native options are stored per engine.
  • Expose missing M7A documentation and SRA profile fallback conditions in the script and user interfaces.
  • Regenerate frontend API models and services for the schema and endpoint changes.
app/task/HSR/AutoProxy.py
app/task/HSR/manager.py
app/task/HSR/task_mapping.py
app/task/HSR/tools/api.py
frontend/src/views/EditView/User/HSRUserEdit/StageConfigSection.vue
frontend/src/views/EditView/User/HSRUserEdit/ManagedTaskSection.vue
frontend/src/views/EditView/Script/HSRScriptEdit.vue
frontend/src/api/models/HSRManagedDroppedOverride.ts
frontend/src/api/models/HSRSRAProfilesData.ts
frontend/src/api/services/HsrService.ts
frontend/src/api/services/Service.ts
Correct HSR managed-field semantics and user-facing terminology for SRA task configuration.
  • Map Trailblaze Power replenish values to backup power, fuel, and stellar jade in the SRA-defined order.
  • Add Currency Wars刷开局 mode and document its four reroll condition formats.
  • Add localized labels, descriptions, validation ranges, engine descriptions, snapshot/live-config terminology, and reset confirmations.
app/task/HSR/tools/managed_config.py
frontend/src/i18n/locales/en-US.ts
frontend/src/i18n/locales/ja-JP.ts
frontend/src/i18n/locales/zh-CN.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

**历战余响被标成差分宇宙(英文)**:`edit.divergentUniverse` 这个 key 实际
承载的是「历战余响」,中文是「历战余响」、日文是「歴戦余韻」,只有英文照着
key 名翻成了 "Divergent Universe"。而差分宇宙在同一个用户页上真实存在,英文
用户会看到两个 "Divergent Universe" 却指两件事。同源的
`divergentUniverseStartDay`、`pickDivergentUniverseStage` 与 `startDayIfIt`
的英文正文有同样的错译,一并改正;三个 key 顺带改名为 `echoOfWar` /
`echoOfWarStartDay` / `pickEchoOfWarStage`,让下一个翻译的人不会再被带偏。
引用点除 HSR 外还有 SRC 的体力配置区(同样是历战余响,`name="EchoOfWar"`),
一并更新——SRC 的英文界面此前有同一处错标。SRC 自己的
`pickDivergentUniverseStage2/3` 是另外两个 key,未改动。

**体力配置沿用了明日方舟的译法**:`sanityConfiguration` 英文是
"Sanity configuration"、日文是「理性の設定」,"Sanity"/「理性」都是明日方舟
的理智;星穹铁道对应的是开拓力,改为 "Trailblaze Power" 与「開拓力の設定」。

**侵蚀隧洞英文名复数有误**:"Caverns of Corrosion" → "Cavern of Corrosion",
与游戏内官方名称一致。

这两个 key 都只有 HSR 在用(已 grep 确认),不影响其它专项。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@qiyinxi
qiyinxi merged commit 02f6c4b into AUTO-MAS-Project:dev Sep 5, 2026
3 checks passed
@qiyinxi
qiyinxi deleted the feat/hsr-experience-20260905 branch September 5, 2026 16:48
qiyinxi added a commit that referenced this pull request Sep 5, 2026
补一个在上一个 PR 合并时掉队的提交。

[#569](#569) 合并时,GitHub
的 PR 对象没有跟上分支的最后一次推送(head 停在倒数第二个提交,`updated_at` 也没动),所以这一条没有进
dev。分支本身当时是完整的,掉的是整个提交,没有掉一半——dev 上组件仍是硬编码中文、也没有引用不存在的
key,所以合并后的状态是自洽的,只是这项改进缺了。

## 内容

HSR
用户页有一批面向用户的文案从未进过词表,英文和日文用户直接看到中文:页面标题、「用户名」与「剩余天数」两个标签、历战余响与周常的「本周已完成 /
未完成」和「最近完成」、服务器的「官服」、刷取副本下拉的四个副本名、以及 MAS 管控任务列表里的「动态 N 项」「读取自」「周常 /
日常」「三月七」「未读取到原生配置」「已启用 · N 项配置」等。

这几个组件是在上一轮英文化(#487)之后才重做的,所以漏在了外面。仓库的前端 Skill 把「面向用户的文案走词表」列为红线。

新增 17 个 key,三份词表顺序一致;能复用的既有 key
都复用了(`edit.username`、`edit.daysLeft`、`edit.weekly`、`edit.calyxGolden`
等)。英文与日文用游戏官方术语。

## 刻意没动的中文

按仓库既定口径,**被程序拿去做判断的中文一律不翻**:`StageConfigSection` 里
`categoryKeysByChannel`、`isEowCategory`、`stageTagColor` 拿去和后端返回的
`categoryKey` 比对的那几处,以及 `useHSRPluginApi` 里比对后端 warning
前缀的字串,全部保持原样。日志与报错提示同样按既定口径跳过。下拉选项只翻 `label`,`value` 一个没动。

## 本地验证

```
前端  yarn typecheck / lint    退出码 0
      yarn test                40 files / 385 tests passed(含词表 key 一致性与转义校验)
后端  pytest tests             499 passed, 3 skipped
      pytest --collect-only    502 collected,退出码 0
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

## Sourcery 摘要

为支持的语言本地化 HSR 用户页面中剩余的面向用户的文本。

错误修复:
- 将 HSR 用户页面中剩余的硬编码中文文本替换为本地化翻译,以便英语和日语用户能够看到经过翻译的界面内容。

功能增强:
- 在适用的情况下复用现有翻译键,并在中文、英语和日语语言文件中添加缺失的 HSR 专用标签、状态、摘要和阶段选择消息。
- 保持面向后端的值和诊断文本不变,仅本地化用户可见的标签和消息。

<details>
<summary>Original summary in English</summary>

## Summary by Sourcery

Localize the remaining user-facing HSR user-page text across supported
languages.

Bug Fixes:
- Replace remaining hard-coded Chinese text in the HSR user pages with
localized translations so English and Japanese users see translated UI
content.

Enhancements:
- Reuse existing translation keys where applicable and add the missing
HSR-specific labels, statuses, summaries, and stage-selection messages
across Chinese, English, and Japanese locale files.
- Keep backend-facing values and diagnostic text unchanged while
localizing only user-visible labels and messages.

</details>

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant