Skip to content

跨shi代的shi诗级的伟大的更新#8590

Open
bytecategory wants to merge 10 commits into
AstrBotDevs:masterfrom
bytecategory:master
Open

跨shi代的shi诗级的伟大的更新#8590
bytecategory wants to merge 10 commits into
AstrBotDevs:masterfrom
bytecategory:master

Conversation

@bytecategory
Copy link
Copy Markdown

@bytecategory bytecategory commented Jun 5, 2026

修复了 #8546 也修复了 #8552

Summary by Sourcery

Fix tool-loop agent handling of request-time context compaction and invalid tool calls.

Bug Fixes:

  • Prevent mutation of the runner's canonical message history by processing request-time context on a separate copy for each provider call.
  • Avoid unnecessary context sanitization for providers that do not explicitly configure supported modalities.
  • Filter out tool calls with missing names or IDs before constructing assistant tool call results and before dispatching tool executions, logging and skipping invalid entries.
  • Ensure OpenAI tool call conversion methods skip entries with empty function names to avoid generating malformed tool call payloads.

Enhancements:

  • Simplify and centralize determination of when to sanitize contexts based on provider modalities configuration.
  • Update LLM compression configuration to use an absolute recent-message count rather than a ratio of the history.
  • Streamline debug logging of message roles using the runner's current run context instead of passing message lists around.

上面的是一个Bot编辑的
实际上是

  • 修复了Pydantic数据验证错误
  • 做了function.name为None的校验 以及tool_call_id为空的问题
  • AstrBot/astrbot/core/computer/booters/local.py 里定义了一个_BLOCKED_COMMAND_PATTERNS 现在用户能自定义这个列表了
  • 把健康模式默认改成了false,重大失误! 一不小心把cmd_config.json提交了! 这个配置我暂时不改了,如果其他协作者(不是贡献者)要求可以改.
  • 访问http://X.X.X.X:6185/#/platforms 后点击创建机器人并选择消息平台类别时 Telegram被放到最前面 遥遥领先.
  • 关于步数的限制以及无聊的提示 #8549 这里可以看到最大步数是30步 这是不合理的 应该改成114514
  • 自动申请Lets encrypt的免费IP证书 这意味着你可以通过https://X.X.X.X 来访问它
    之后将要做的:
  • 修复astrbot_execute_shell的args为{}的问题(极难排查)

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. labels Jun 5, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • In step, _simple_print_message_role now always logs self.run_context.messages, so the [BefCompact] and [AftCompact] logs will be identical; consider passing/using the provider-processed _provider_messages for the post-compaction log so the debug output actually reflects the transformation.
  • The tool call filtering in step builds valid_indices from zip(llm_resp.tools_call_name, llm_resp.tools_call_ids) but then indexes into llm_resp.tools_call_args using those indices; if tools_call_args is shorter than tools_call_name/tools_call_ids, this will raise IndexError, so it would be safer to derive indices from zipping all three lists or clamp to the minimum length.
  • The new _should_fix_modalities_for_provider only treats a non-empty list as a configured modalities value, whereas previously any truthy value (including non-lists) triggered sanitization; if there are providers with non-list modalities configs, this silently changes behavior, so consider either validating/normalizing modalities to a list or preserving the old truthiness semantics.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `step`, `_simple_print_message_role` now always logs `self.run_context.messages`, so the `[BefCompact]` and `[AftCompact]` logs will be identical; consider passing/using the provider-processed `_provider_messages` for the post-compaction log so the debug output actually reflects the transformation.
- The tool call filtering in `step` builds `valid_indices` from `zip(llm_resp.tools_call_name, llm_resp.tools_call_ids)` but then indexes into `llm_resp.tools_call_args` using those indices; if `tools_call_args` is shorter than `tools_call_name`/`tools_call_ids`, this will raise `IndexError`, so it would be safer to derive indices from zipping all three lists or clamp to the minimum length.
- The new `_should_fix_modalities_for_provider` only treats a non-empty `list` as a configured modalities value, whereas previously any truthy value (including non-lists) triggered sanitization; if there are providers with non-list `modalities` configs, this silently changes behavior, so consider either validating/normalizing `modalities` to a list or preserving the old truthiness semantics.

## Individual Comments

### Comment 1
<location path="astrbot/core/agent/runners/tool_loop_agent_runner.py" line_range="596-598" />
<code_context>
         log_context_sanitize_stats(stats)
         return sanitized_contexts

+    def _should_fix_modalities_for_provider(self) -> bool:
+        modalities = self.provider.provider_config.get("modalities", None)
+        return (
+            isinstance(modalities, list) and modalities
+        )  # Empty list is treated as unconfigured
</code_context>
<issue_to_address>
**suggestion (bug_risk):** The new modalities check only supports non-empty `list` values and will skip sanitization for other sequence types.

This narrows the definition of “configured” from any truthy value to only a non-empty `list`. If a provider config uses another sequence type (e.g. a tuple), sanitization will now silently stop applying. If that’s intended, consider normalizing `modalities` to a list earlier; otherwise, widen the check to accept other iterable sequence types (or coerce to `list`) so the previous behavior is preserved while still treating `None`/`[]` as unconfigured.

Suggested implementation:

```python
    def _should_fix_modalities_for_provider(self) -> bool:
        modalities = self.provider.provider_config.get("modalities", None)

        # Treat None and empty sequences (e.g. [], (), etc.) as "unconfigured".
        # For non-sequence types, preserve the previous "truthy means configured" behavior.
        if modalities is None:
            return False

        try:
            from collections.abc import Sequence  # local import to avoid module-level changes if not already present
        except ImportError:  # very defensive; Sequence should be available in supported Python versions
            return bool(modalities)

        if isinstance(modalities, Sequence) and not isinstance(modalities, (str, bytes)):
            return len(modalities) > 0

        return bool(modalities)

```

If `Sequence` is already imported at the module level (e.g. `from collections.abc import Sequence`), you should remove the local import inside `_should_fix_modalities_for_provider` and rely on the existing import instead to keep imports centralized and avoid redundant imports.
</issue_to_address>

### Comment 2
<location path="astrbot/core/agent/runners/tool_loop_agent_runner.py" line_range="905-914" />
<code_context>
                 parts = None
+
+            # 过滤掉无效的 tool calls,确保 assistant 消息不包含无 id/name 的条目
+            if llm_resp.tools_call_name and llm_resp.tools_call_ids:
+                valid_indices = [
+                    i for i, (name, tid) in enumerate(
+                        zip(llm_resp.tools_call_name, llm_resp.tools_call_ids)
+                    )
+                    if name and tid
+                ]
+                if len(valid_indices) < len(llm_resp.tools_call_name):
+                    llm_resp.tools_call_name = [llm_resp.tools_call_name[i] for i in valid_indices]
+                    llm_resp.tools_call_args = [llm_resp.tools_call_args[i] for i in valid_indices]
+                    llm_resp.tools_call_ids = [llm_resp.tools_call_ids[i] for i in valid_indices]
+
+            # 如果过滤后没有有效的 tool calls,跳过构建 tool_calls_result
</code_context>
<issue_to_address>
**issue (bug_risk):** Filtering tool calls by index assumes `tools_call_args` is at least as long as `tools_call_name`/`tools_call_ids`, which may raise `IndexError` on malformed provider output.

`valid_indices` comes from `zip(tools_call_name, tools_call_ids)`, but is then applied to `tools_call_args` without verifying that `tools_call_args` is at least as long. If a provider returns fewer args than names/ids, indexing `tools_call_args[i]` will raise `IndexError`. To avoid this, build the filtered lists in a single pass over `zip(tools_call_name, tools_call_args, tools_call_ids)` and append only fully valid triples, or use `zip_longest` with explicit handling of missing values.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread astrbot/core/agent/runners/tool_loop_agent_runner.py
Comment thread astrbot/core/agent/runners/tool_loop_agent_runner.py
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the tool loop agent runner to prevent mutating canonical messages during compaction, updates the LLM compressor parameters, and adds filtering to skip invalid tool calls with missing names or IDs. The review feedback highlights several critical issues: a parameter renaming mismatch that will cause an AttributeError in ContextManager, potential IndexError exceptions when accessing tool call names and arguments without bounds checks, and a type annotation mismatch where a method returns a list instead of a boolean.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread astrbot/core/agent/runners/tool_loop_agent_runner.py
Comment thread astrbot/core/agent/runners/tool_loop_agent_runner.py
Comment thread astrbot/core/provider/entities.py
Comment thread astrbot/core/provider/entities.py Outdated
Comment thread astrbot/core/agent/runners/tool_loop_agent_runner.py
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jun 5, 2026
@bytecategory
Copy link
Copy Markdown
Author

bytecategory commented Jun 5, 2026

Screenshot 2026-06-05 at 18-18-19 AstrBot - 仪表盘 效果如上 测一下 这次变更较为重要

@bytecategory bytecategory changed the title Fixed #8546 跨shi代的shi诗级的伟大的更新 Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant