Skip to content

feat: 迷失之地-利用绝区零交互机制, 减少迷失之地开局重复交互的可能性 - #2353

Merged
ShadowLemoon merged 9 commits into
OneDragon-Anything:mainfrom
JoshCai233:lost-void-first-room-npc
Aug 9, 2026
Merged

feat: 迷失之地-利用绝区零交互机制, 减少迷失之地开局重复交互的可能性#2353
ShadowLemoon merged 9 commits into
OneDragon-Anything:mainfrom
JoshCai233:lost-void-first-room-npc

Conversation

@JoshCai233

@JoshCai233 JoshCai233 commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

大家可以先测一测

Summary by CodeRabbit

Bug Fixes

  • 修复特定场景下 NPC 重复交互:开场/入口区域允许对同一目标进行必要重试,并新增开局特殊交互完成状态追踪,避免同一阶段被重复触发。
  • 优化交互后的 NPC 移动:根据交互对象类型与首次开局特殊条件,执行更精确的前移/微移或右移;其它 NPC 提供默认后退兜底。
  • 调整交互提示表述:将“转动”改为“转动视角”。

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

LostVoidRunLevel 新增 ao_fei_li_ya_talked 状态,调整了入口场景的重复交互判定与 NPC 交互后移动分支;LostVoidDetector 的交互类识别改为常量引用,并细化了一处注释表述。

Changes

LostVoid 交互状态与代码质量优化

Layer / File(s) Summary
Detector 类别常量引用
src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
__debug() 中用于判断交互类的 is_frame_with 实参由字符串字面量改为 LostVoidDetector.CLASS_INTERACT 常量。
交互状态与入口移动分支
src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
__init__ 新增 ao_fei_li_ya_talked 布尔状态;non_battle_check 的未找到目标注释改为“转动视角”;try_interact 将重复交互拦截限定为非 ENTRY 场景;move_after_interact 重构 ENTRY 下 NPC 交互后的移动,按 AO_FEI_LI_YASCGMDYJY 与其他 NPC 分流处理。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 交互一回又一回,标记悄悄藏心扉,
常量代替旧字样,耳朵一竖更清脆。
前进左移轻轻走,右移后退各自归,
LostVoid 路径更分明,萝卜也跟着笑开怀。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题与变更内容一致,准确概括了利用交互机制减少迷失之地开局重复交互的主要改动。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 672-683: The condition for setting the one-time flag
`ao_fei_li_ya_talked` depends on accurate name identification
(`self.interact_target.name == LostVoidInteractNPC.AO_FEI_LI_YA.value`), but the
comment explicitly states that name identification is unreliable in this
scenario, creating a logical conflict that breaks the one-time behavior. Reorder
the conditional logic to check and handle the `SCGMDYJY` special case first,
then restructure the flag-setting logic so that `ao_fei_li_ya_talked` is set
primarily based on the `not self.ao_fei_li_ya_talked` condition rather than
depending heavily on the unreliable AO name check, thereby weakening the name
validation dependency for the one-time interaction path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a205340f-e019-4e3f-a807-bf9fcc6a135e

📥 Commits

Reviewing files that changed from the base of the PR and between ba2424d and d789f13.

📒 Files selected for processing (1)
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

@kawayiYokami

Copy link
Copy Markdown
Contributor

对于垃圾电脑这个移动真的有效吗?

我不清楚,cai先生如果实测没问题,那就没问题。

只是这个可能大规模用户使用时会出现很多意想不到的事情。

因你这个按时间移动本质上不是什么更完美的算法

@JoshCai233

JoshCai233 commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

对于垃圾电脑这个移动真的有效吗?

我不清楚,cai先生如果实测没问题,那就没问题。

只是这个可能大规模用户使用时会出现很多意想不到的事情。

因你这个按时间移动本质上不是什么更完美的算法

所以要大家测测啊:

  1. 向前移动是为了和 奥菲利亚 贴贴,左转向是让角色面向左边。绝区零的逻辑是和npc贴贴时不面向npc就不会点击npc,所以只要执行了这两个指令就会让角色点到
  2. 即使第一次向左前走的指令没有点击到 ,之后就不会再向左前走了,会回到之前向后走2s的逻辑。
  3. 所以目前我能想到的使位置产生异常的情况只有第一次向左前走多了,然后走到两个npc背后的角落里面卡住了,比如卡键之类的

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Line 680: In the line where is_frame_with_all(frame_result) is called in the
lost_void_run_level.py file, the unpacked variables with_distance and with_entry
are not being used, which triggers the Ruff RUF059 warning. Replace these unused
variable names with underscore placeholders (such as _ or _unused) to explicitly
indicate that these values are intentionally ignored. Only keep with_interact as
a named variable since it is actually used in the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 512ecb53-84f8-49bf-9be0-1a58e91262f1

📥 Commits

Reviewing files that changed from the base of the PR and between b5382c4 and 3800b3d.

📒 Files selected for processing (1)
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

Comment thread src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py (1)

69-89: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

is_frame_with 存在可达的 TypeError 路径

target_type 走默认值 None 时,Line 87 的 in target_type 会直接抛异常;且前面构建的 target_type_set 没有被使用。建议统一用集合做匹配并在空目标时直接返回 False

建议修复
 def is_frame_with(self, frame_result: DetectFrameResult | None = None,
-                  target_type: list[str] | str = None) -> bool:
+                  target_type: list[str] | str | None = None) -> bool:
@@
-    target_type_set = set()
+    target_type_set: set[str] = set()
     if isinstance(target_type, str):
         target_type_set.add(target_type)
     elif isinstance(target_type, list):
         target_type_set.update(target_type)
+    else:
+        return False
     for result in frame_result.results:
-        if result.detect_class.class_name in target_type:
+        if result.detect_class.class_name in target_type_set:
             return True
     return False
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`
around lines 69 - 89, `LostVoidDetector.is_frame_with` has a reachable
`TypeError` when `target_type` is left as the default `None`, because the
membership check still uses `target_type` instead of the prepared set. Update
the method to use `target_type_set` for class-name matching in the loop, and add
an early `False` return when `target_type` is empty or not provided. Keep the
fix localized to `is_frame_with` and preserve the existing `frame_result`
fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Line 70: The function signature in lost_void_detector.py has a mismatch
between the default value and the type annotation for target_type: it defaults
to None but is only annotated as list[str] | str. Update the affected method
signature and any related type hints so target_type explicitly includes None,
using list[str] | str | None for the parameter and str | None where the return
or related annotation applies, keeping the annotation aligned with the existing
behavior.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 523-527: The repeat-interaction early return in LostVoidRunLevel
should not send control back without changing state, because the same target can
be re-detected and retried indefinitely. In the current current_interact_target
/ target_key / interacted_target_key_list flow, add a small escape action before
returning round_fail('重复交互对象'), or make the repeated target part of the later
ignore/filter logic used by the non-combat detection path so it won’t be
selected again.
- Around line 405-414: 在 lost_void_run_level.py 的这段强制刷新逻辑里,先通过
agent_context.team_info 取到 team_info 并校验是否为空,再调用 request_check_all_agents();当前在
LostVoidRunLevel 相关流程中直接解引用 team_info 会导致未初始化时崩溃,而后续又把 team_info is None
视为合法分支。请把空值检查前移到 agent_context.team_info/request_check_all_agents 之前,并保留对
team_info.agent_list 的后续判空逻辑。

---

Outside diff comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Around line 69-89: `LostVoidDetector.is_frame_with` has a reachable
`TypeError` when `target_type` is left as the default `None`, because the
membership check still uses `target_type` instead of the prepared set. Update
the method to use `target_type_set` for class-name matching in the loop, and add
an early `False` return when `target_type` is empty or not provided. Keep the
fix localized to `is_frame_with` and preserve the existing `frame_result`
fallback behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 22f8862b-cdc5-4492-bfa9-f794ebac8a00

📥 Commits

Reviewing files that changed from the base of the PR and between c84914e and e6a0381.

📒 Files selected for processing (2)
  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py (1)

69-89: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

is_frame_with 存在可达的 TypeError 路径

target_type 走默认值 None 时,Line 87 的 in target_type 会直接抛异常;且前面构建的 target_type_set 没有被使用。建议统一用集合做匹配并在空目标时直接返回 False

建议修复
 def is_frame_with(self, frame_result: DetectFrameResult | None = None,
-                  target_type: list[str] | str = None) -> bool:
+                  target_type: list[str] | str | None = None) -> bool:
@@
-    target_type_set = set()
+    target_type_set: set[str] = set()
     if isinstance(target_type, str):
         target_type_set.add(target_type)
     elif isinstance(target_type, list):
         target_type_set.update(target_type)
+    else:
+        return False
     for result in frame_result.results:
-        if result.detect_class.class_name in target_type:
+        if result.detect_class.class_name in target_type_set:
             return True
     return False
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`
around lines 69 - 89, `LostVoidDetector.is_frame_with` has a reachable
`TypeError` when `target_type` is left as the default `None`, because the
membership check still uses `target_type` instead of the prepared set. Update
the method to use `target_type_set` for class-name matching in the loop, and add
an early `False` return when `target_type` is empty or not provided. Keep the
fix localized to `is_frame_with` and preserve the existing `frame_result`
fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Line 70: The function signature in lost_void_detector.py has a mismatch
between the default value and the type annotation for target_type: it defaults
to None but is only annotated as list[str] | str. Update the affected method
signature and any related type hints so target_type explicitly includes None,
using list[str] | str | None for the parameter and str | None where the return
or related annotation applies, keeping the annotation aligned with the existing
behavior.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 523-527: The repeat-interaction early return in LostVoidRunLevel
should not send control back without changing state, because the same target can
be re-detected and retried indefinitely. In the current current_interact_target
/ target_key / interacted_target_key_list flow, add a small escape action before
returning round_fail('重复交互对象'), or make the repeated target part of the later
ignore/filter logic used by the non-combat detection path so it won’t be
selected again.
- Around line 405-414: 在 lost_void_run_level.py 的这段强制刷新逻辑里,先通过
agent_context.team_info 取到 team_info 并校验是否为空,再调用 request_check_all_agents();当前在
LostVoidRunLevel 相关流程中直接解引用 team_info 会导致未初始化时崩溃,而后续又把 team_info is None
视为合法分支。请把空值检查前移到 agent_context.team_info/request_check_all_agents 之前,并保留对
team_info.agent_list 的后续判空逻辑。

---

Outside diff comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Around line 69-89: `LostVoidDetector.is_frame_with` has a reachable
`TypeError` when `target_type` is left as the default `None`, because the
membership check still uses `target_type` instead of the prepared set. Update
the method to use `target_type_set` for class-name matching in the loop, and add
an early `False` return when `target_type` is empty or not provided. Keep the
fix localized to `is_frame_with` and preserve the existing `frame_result`
fallback behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 22f8862b-cdc5-4492-bfa9-f794ebac8a00

📥 Commits

Reviewing files that changed from the base of the PR and between c84914e and e6a0381.

📒 Files selected for processing (2)
  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
🛑 Comments failed to post (3)
src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py (1)

70-70: 📐 Maintainability & Code Quality | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

sed -n '65,95p' src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 1351


将参数类型显式包含 None

target_type 参数的默认值为 None,但类型注解中缺少 | None,会导致类型提示与实际行为不符。请修改为 list[str] | str | Nonestr | None

🧰 Tools
🪛 Ruff (0.15.18)

[warning] 70-70: PEP 484 prohibits implicit Optional

Convert to T | None

(RUF013)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`
at line 70, The function signature in lost_void_detector.py has a mismatch
between the default value and the type annotation for target_type: it defaults
to None but is only annotated as list[str] | str. Update the affected method
signature and any related type hints so target_type explicitly includes None,
using list[str] | str | None for the parameter and str | None where the return
or related annotation applies, keeping the annotation aligned with the existing
behavior.

Sources: Coding guidelines, Linters/SAST tools

src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py (2)

405-414: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

先校验 team_info 再解引用。

Line 407 已直接调用 agent_context.team_info.request_check_all_agents(),但 Line 413 又把 team_info is None 当作可能情况处理;如果队伍信息尚未初始化,这里会先崩溃。

建议修改
         agent_context = self.ctx.auto_battle_context.agent_context
+        team_info = agent_context.team_info
+        if team_info is None:
+            log.info('战斗上下文暂无队伍信息,跳过代理人类型优先级追加')
+            return self.round_success(status='非战斗区域')
+
         log.info('追加代理人类型优先级前,强制刷新一次战斗上下文队伍信息')
-        agent_context.team_info.request_check_all_agents()
+        team_info.request_check_all_agents()
         self.screenshot()
         agent_context._last_check_agent_time = 0
         agent_context.check_agent_related(self.last_screenshot, self.last_screenshot_time)
         team_info = agent_context.team_info
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        agent_context = self.ctx.auto_battle_context.agent_context
        team_info = agent_context.team_info
        if team_info is None:
            log.info('战斗上下文暂无队伍信息,跳过代理人类型优先级追加')
            return self.round_success(status='非战斗区域')

        log.info('追加代理人类型优先级前,强制刷新一次战斗上下文队伍信息')
        team_info.request_check_all_agents()
        self.screenshot()
        agent_context._last_check_agent_time = 0
        agent_context.check_agent_related(self.last_screenshot, self.last_screenshot_time)
        team_info = agent_context.team_info

        if team_info is None or team_info.agent_list is None or len(team_info.agent_list) == 0:
            log.info('战斗上下文强制刷新后仍暂无队伍信息,跳过代理人类型优先级追加')
🧰 Tools
🪛 Ruff (0.15.18)

[warning] 406-406: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


[warning] 414-414: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 405 - 414, 在 lost_void_run_level.py 的这段强制刷新逻辑里,先通过
agent_context.team_info 取到 team_info 并校验是否为空,再调用 request_check_all_agents();当前在
LostVoidRunLevel 相关流程中直接解引用 team_info 会导致未初始化时崩溃,而后续又把 team_info is None
视为合法分支。请把空值检查前移到 agent_context.team_info/request_check_all_agents 之前,并保留对
team_info.agent_list 的后续判空逻辑。

523-527: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

重复对象返回上游前需要改变当前位置或忽略条件。

这里直接 round_fail('重复交互对象') 会回到 非战斗画面识别,但后续检测只使用 had_been_list,没有消费这个 target_key;如果该交互标记仍在画面里,可能反复锁定同一对象直到超时。建议在返回前执行一次脱离移动,或把该对象纳入后续检测的忽略策略。

一种局部修复方式
                 target_key = self.get_interact_target_key(current_interact_target)
                 if self.region_type != LostVoidRegionType.ENTRY and target_key in self.interacted_target_key_list:
+                    self.interact_target = current_interact_target
+                    self.move_after_interact()
                     log.info('当前层已交互过 %s,本次不再交互,返回上游继续处理', target_key)
                     return self.round_fail('重复交互对象')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            if current_interact_target is not None:
                target_key = self.get_interact_target_key(current_interact_target)
                if self.region_type != LostVoidRegionType.ENTRY and target_key in self.interacted_target_key_list:
                    self.interact_target = current_interact_target
                    self.move_after_interact()
                    log.info('当前层已交互过 %s,本次不再交互,返回上游继续处理', target_key)
                    return self.round_fail('重复交互对象')
🧰 Tools
🪛 Ruff (0.15.18)

[warning] 526-526: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


[warning] 526-526: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 523 - 527, The repeat-interaction early return in LostVoidRunLevel
should not send control back without changing state, because the same target can
be re-detected and retried indefinitely. In the current current_interact_target
/ target_key / interacted_target_key_list flow, add a small escape action before
returning round_fail('重复交互对象'), or make the repeated target part of the later
ignore/filter logic used by the non-combat detection path so it won’t be
selected again.

@JoshCai233

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py (1)

805-821: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

with_interact 不能判断“右侧是否还有第二个 NPC”。

这里的布尔值只表示画面里还存在任意一个 CLASS_INTERACT,并不能区分“只有当前 NPC 剩余的感叹号”还是“右侧还有第二个目标”。这样兜底的 move_s 很可能不会触发,首次交互后会过早进入 move_w + move_a 分支,和注释里描述的 fallback 条件不一致。

建议修改
-                    with_interact = self.ctx.lost_void.detector.is_frame_with(frame_result, LostVoidDetector.CLASS_INTERACT)
-                    if not with_interact:
+                    interact_count = sum(
+                        1
+                        for result in frame_result.results
+                        if result.detect_class.class_name == LostVoidDetector.CLASS_INTERACT
+                    )
+                    if interact_count < 2:
                         # 如果开局右边只有一个npc, 交互完正常后退
                         default_move_back = True
                     else:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 805 - 821, `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Around line 69-70: `is_frame_with` is still checking the raw `target_type`
instead of the normalized set, which can cause a membership test on `None` when
the argument is omitted. Update `LostVoidDetector.is_frame_with` to use the
already-built `target_type_set` for the comparison, and adjust `get_result_by_x`
so its `target_type` parameter is typed as `str | None` to match the intended
usage and avoid null-handling issues.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 395-415: `append_agent_type_priority()`
缺少从“追加代理人类型优先级”返回到后续流程的回流节点,导致成功后 `execute()` 无法继续。请在 `lost_void_run_level.py`
中围绕 `append_agent_type_priority` / `@operation_node(name='追加代理人类型优先级')` 补上对应的
`@node_from(from_name='追加代理人类型优先级')` 跳转,确保成功返回后能继续进入 `非战斗画面识别` 或其对应的下一步节点,而不是让
`_get_next_node()` 直接结束。

---

Outside diff comments:
In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 805-821: `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a3253465-714e-4092-a406-5c283b406a14

📥 Commits

Reviewing files that changed from the base of the PR and between c84914e and e6a0381.

📒 Files selected for processing (2)
  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py (1)

805-821: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

with_interact 不能判断“右侧是否还有第二个 NPC”。

这里的布尔值只表示画面里还存在任意一个 CLASS_INTERACT,并不能区分“只有当前 NPC 剩余的感叹号”还是“右侧还有第二个目标”。这样兜底的 move_s 很可能不会触发,首次交互后会过早进入 move_w + move_a 分支,和注释里描述的 fallback 条件不一致。

建议修改
-                    with_interact = self.ctx.lost_void.detector.is_frame_with(frame_result, LostVoidDetector.CLASS_INTERACT)
-                    if not with_interact:
+                    interact_count = sum(
+                        1
+                        for result in frame_result.results
+                        if result.detect_class.class_name == LostVoidDetector.CLASS_INTERACT
+                    )
+                    if interact_count < 2:
                         # 如果开局右边只有一个npc, 交互完正常后退
                         default_move_back = True
                     else:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 805 - 821, `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Around line 69-70: `is_frame_with` is still checking the raw `target_type`
instead of the normalized set, which can cause a membership test on `None` when
the argument is omitted. Update `LostVoidDetector.is_frame_with` to use the
already-built `target_type_set` for the comparison, and adjust `get_result_by_x`
so its `target_type` parameter is typed as `str | None` to match the intended
usage and avoid null-handling issues.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 395-415: `append_agent_type_priority()`
缺少从“追加代理人类型优先级”返回到后续流程的回流节点,导致成功后 `execute()` 无法继续。请在 `lost_void_run_level.py`
中围绕 `append_agent_type_priority` / `@operation_node(name='追加代理人类型优先级')` 补上对应的
`@node_from(from_name='追加代理人类型优先级')` 跳转,确保成功返回后能继续进入 `非战斗画面识别` 或其对应的下一步节点,而不是让
`_get_next_node()` 直接结束。

---

Outside diff comments:
In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 805-821: `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a3253465-714e-4092-a406-5c283b406a14

📥 Commits

Reviewing files that changed from the base of the PR and between c84914e and e6a0381.

📒 Files selected for processing (2)
  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
🛑 Comments failed to post (2)
src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py (1)

69-70: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py'

echo '--- outline ---'
ast-grep outline "$file" --view expanded || true

echo '--- relevant lines ---'
sed -n '1,180p' "$file" | cat -n

echo '--- search for usages of is_frame_with / get_result_by_x ---'
rg -n "is_frame_with\(|get_result_by_x\(" src || true

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 8558


is_frame_with 仍在使用原始 target_type

target_type_set 已经构造出来,但后面的判断没有用它;is_frame_with() 省略参数时会在 None 上做成员测试报错。顺手把 get_result_by_xtarget_type 改成 str | None

🧰 Tools
🪛 Ruff (0.15.18)

[warning] 70-70: PEP 484 prohibits implicit Optional

Convert to T | None

(RUF013)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`
around lines 69 - 70, `is_frame_with` is still checking the raw `target_type`
instead of the normalized set, which can cause a membership test on `None` when
the argument is omitted. Update `LostVoidDetector.is_frame_with` to use the
already-built `target_type_set` for the comparison, and adjust `get_result_by_x`
so its `target_type` parameter is typed as `str | None` to match the intended
usage and avoid null-handling issues.

Sources: Coding guidelines, Linters/SAST tools

src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py (1)

395-415: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Inspect the target file around the relevant sections
sed -n '360,460p' src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
printf '\n===== NEXT =====\n'
sed -n '720,840p' src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

# 2) Find all node_from usages for the new node and the upstream loop node
printf '\n===== NODE LINKS =====\n'
rg -n "`@node_from`\(from_name='追加代理人类型优先级'|`@node_from`\(from_name='非战斗画面识别'|`@node_from`\(from_name='更新优先级'" src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

# 3) Inspect the decorators / framework contract for node_from and operation_node
printf '\n===== DECORATORS =====\n'
rg -n "def node_from|def operation_node|class .*Operation" src/zzz_od -g '*.py'

# 4) Inspect detector.is_frame_with semantics
printf '\n===== DETECTOR SEMANTICS =====\n'
rg -n "def is_frame_with|class .*Detector|CLASS_INTERACT" src/zzz_od -g '*.py'

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 21980


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '===== LOST VOID DETECTOR =====\n'
sed -n '1,170p' src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py

printf '\n===== OPERATION FLOW CONTRACT =====\n'
rg -n "node_from|operation_node|success=False|status=" src/zzz_od/operation src/zzz_od/application -g '*.py' | sed -n '1,220p'

printf '\n===== NODE FROM DEFINITIONS =====\n'
rg -n "def node_from|class .*OperationNode|class .*Node" src/zzz_od -g '*.py'

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 30037


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '===== OPERATION EDGE / NODE DEFINITIONS =====\n'
python3 - <<'PY'
from pathlib import Path

paths = [
    "src/one_dragon/base/operation/operation_edge.py",
    "src/one_dragon/base/operation/operation_node.py",
    "src/one_dragon/base/operation/operation.py",
    "src/one_dragon/base/operation/operation_round_result.py",
]
for p in paths:
    path = Path(p)
    if path.exists():
        print(f"\n--- {p} ---")
        with path.open("r", encoding="utf-8") as f:
            for i, line in enumerate(f, 1):
                if i <= 260:
                    print(f"{i:4d}: {line.rstrip()}")
                else:
                    break
PY

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 18456


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '470,520p' src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 2646


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '260,420p' src/one_dragon/base/operation/operation.py

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 5449


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "def _execute_one_round|_node_edges_map|current_node|next_node|edge_list|ignore_status|round_success|round_fail" src/one_dragon/base/operation/operation.py
sed -n '420,620p' src/one_dragon/base/operation/operation.py

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 14410


补上 追加代理人类型优先级 的回流边

append_agent_type_priority() 现在成功后只返回 status='非战斗区域',但没有任何 @node_from(from_name='追加代理人类型优先级') 接回 非战斗画面识别。按当前框架,_get_next_node() 会直接返回 Noneexecute() 随即结束,首次补完优先级后流程就断了。

🧰 Tools
🪛 Ruff (0.15.18)

[warning] 403-403: Docstring contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF002)


[warning] 406-406: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


[warning] 414-414: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 395 - 415, `append_agent_type_priority()`
缺少从“追加代理人类型优先级”返回到后续流程的回流节点,导致成功后 `execute()` 无法继续。请在 `lost_void_run_level.py`
中围绕 `append_agent_type_priority` / `@operation_node(name='追加代理人类型优先级')` 补上对应的
`@node_from(from_name='追加代理人类型优先级')` 跳转,确保成功返回后能继续进入 `非战斗画面识别` 或其对应的下一步节点,而不是让
`_get_next_node()` 直接结束。

@JoshCai233

Copy link
Copy Markdown
Contributor Author

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)

src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py (1)> 805-821: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

with_interact 不能判断“右侧是否还有第二个 NPC”。
这里的布尔值只表示画面里还存在任意一个 CLASS_INTERACT,并不能区分“只有当前 NPC 剩余的感叹号”还是“右侧还有第二个目标”。这样兜底的 move_s 很可能不会触发,首次交互后会过早进入 move_w + move_a 分支,和注释里描述的 fallback 条件不一致。

建议修改

-                    with_interact = self.ctx.lost_void.detector.is_frame_with(frame_result, LostVoidDetector.CLASS_INTERACT)
-                    if not with_interact:
+                    interact_count = sum(
+                        1
+                        for result in frame_result.results
+                        if result.detect_class.class_name == LostVoidDetector.CLASS_INTERACT
+                    )
+                    if interact_count < 2:
                         # 如果开局右边只有一个npc, 交互完正常后退
                         default_move_back = True
                     else:

🤖 Prompt for AI Agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`
around lines 805 - 821, `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。

🤖 Prompt for all review comments with AI agents

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py`:
- Around line 69-70: `is_frame_with` is still checking the raw `target_type`
instead of the normalized set, which can cause a membership test on `None` when
the argument is omitted. Update `LostVoidDetector.is_frame_with` to use the
already-built `target_type_set` for the comparison, and adjust `get_result_by_x`
so its `target_type` parameter is typed as `str | None` to match the intended
usage and avoid null-handling issues.

In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 395-415: `append_agent_type_priority()`
缺少从“追加代理人类型优先级”返回到后续流程的回流节点,导致成功后 `execute()` 无法继续。请在 `lost_void_run_level.py`
中围绕 `append_agent_type_priority` / `@operation_node(name='追加代理人类型优先级')` 补上对应的
`@node_from(from_name='追加代理人类型优先级')` 跳转,确保成功返回后能继续进入 `非战斗画面识别` 或其对应的下一步节点,而不是让
`_get_next_node()` 直接结束。

---

Outside diff comments:
In
`@src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py`:
- Around line 805-821: `with_interact` 只能说明当前帧还有交互目标,不能用来判断“右侧是否还有第二个 NPC”,导致
`LostVoidRunLevel` 这里的分支判断和注释里的兜底条件不一致。请在 `lost_void_run_level.py` 中围绕
`detect_to_go()` 和 `detector.is_frame_with()` 的结果,改成能区分“仅剩当前 NPC
的交互提示”与“仍有第二个目标”的判断逻辑,再据此决定是否走默认后退还是进入 `move_w + move_a` 分支,避免提前进入贴贴/左转路径。

🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a3253465-714e-4092-a406-5c283b406a14

📥 Commits
Reviewing files that changed from the base of the PR and between c84914e and e6a0381.

📒 Files selected for processing (2)

  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_detector.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py

🛑 Comments failed to post (2)

只交互了一次的时候,with_interact代表有第二个交互的npc;奥菲利亚一定是第一个交互的npc

@ShadowLemoon

Copy link
Copy Markdown
Collaborator

这个pr还有用吗

@JoshCai233

JoshCai233 commented Jul 30, 2026 via email

Copy link
Copy Markdown
Contributor Author

@ShadowLemoon

Copy link
Copy Markdown
Collaborator

那得解决下冲突

@ShadowLemoon

Copy link
Copy Markdown
Collaborator

#2584 有冲突吗

@kawayiYokami

Copy link
Copy Markdown
Contributor

#2584 有冲突吗

无关

# Conflicts:
#	src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
@JoshCai233

JoshCai233 commented Jul 30, 2026 via email

Copy link
Copy Markdown
Contributor Author

@ShadowLemoon ShadowLemoon added the test-branch 合入 test 分支 label Jul 31, 2026
@github-actions github-actions Bot added the test-conflict 合入 test 分支时冲突,需 rebase label Aug 3, 2026
@ShadowLemoon

Copy link
Copy Markdown
Collaborator

conflict fix plz

# Conflicts:
#	src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
@github-actions github-actions Bot removed the test-conflict 合入 test 分支时冲突,需 rebase label Aug 3, 2026
@JoshCai233

Copy link
Copy Markdown
Contributor Author

conflict fix plz

解决了

@ShadowLemoon
ShadowLemoon merged commit 211f97c into OneDragon-Anything:main Aug 9, 2026
7 of 8 checks passed
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

test-branch 合入 test 分支

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants