Skip to content

fix: preserve guarded run-based tools#8790

Open
zouyonghe wants to merge 1 commit into
AstrBotDevs:masterfrom
zouyonghe:fix/8788-permission-guard-run-tool
Open

fix: preserve guarded run-based tools#8790
zouyonghe wants to merge 1 commit into
AstrBotDevs:masterfrom
zouyonghe:fix/8788-permission-guard-run-tool

Conversation

@zouyonghe

@zouyonghe zouyonghe commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

  • delegate permission-guarded FunctionTool wrappers to underlying run() methods when no handler or overridden call() exists
  • keep run() argument semantics aligned with FunctionToolExecutor by passing the event object
  • add a regression test for dataclass-style plugin tools that implement run()

Fixes #8788.

Verification

  • uv run pytest tests/unit/test_tool_permission.py -q
  • uv run ruff check astrbot/core/provider/func_tool_manager.py tests/unit/test_tool_permission.py
  • uv run ruff format --check astrbot/core/provider/func_tool_manager.py tests/unit/test_tool_permission.py
  • git diff --check

Summary by Sourcery

Ensure permission-guarded tools correctly delegate to underlying run-based tools when no custom call handler is defined.

Bug Fixes:

  • Fix permission-guarded tools so they invoke the wrapped tool's run() method when no handler or overridden call() exists, returning the final result from sync, async, or async-generator implementations.

Tests:

  • Add a regression test verifying that permission-guarded tools delegate to a wrapped tool's run() method and pass through the event context.

@dosubot dosubot Bot added size:S This PR changes 10-29 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 15, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request adds support for delegating tool execution to a wrapped run method in FunctionToolManager when a call_override is not present, handling async generators, awaitables, and synchronous results. It also includes a unit test to verify this behavior. The review feedback points out a potential AttributeError when accessing context.context.event directly and suggests retrieving the event safely using getattr.

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.


run = getattr(self._wrapped, "run", None)
if run is not None:
event = context.context.event

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.

high

In _check_tool_permission, the retrieval of event from context is safely guarded against AttributeError in case context or context.context is missing or not fully formed. However, here event = context.context.event is accessed directly, which can lead to an unhandled AttributeError if a mock or an unexpected context object is passed.

We should retrieve event safely using nested getattr calls to match the robust behavior of _check_tool_permission.

Suggested change
event = context.context.event
event = getattr(getattr(context, "context", None), "event", None)

@sourcery-ai sourcery-ai 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.

Hey - I've left some high level feedback:

  • In the run delegation branch, consider mirroring the call_override logic (e.g., only delegating when run is overridden from FunctionTool.run) to avoid accidentally calling a base/default run implementation on tools that don’t intend to support it.
  • The new run delegation assumes context.context.event always exists; if there are other call sites or context types, it may be safer to access this via a helper or guard against missing attributes to avoid attribute errors in non-chat contexts.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the `run` delegation branch, consider mirroring the `call_override` logic (e.g., only delegating when `run` is overridden from `FunctionTool.run`) to avoid accidentally calling a base/default `run` implementation on tools that don’t intend to support it.
- The new `run` delegation assumes `context.context.event` always exists; if there are other call sites or context types, it may be safer to access this via a helper or guard against missing attributes to avoid attribute errors in non-chat contexts.

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.

@zouyonghe

Copy link
Copy Markdown
Member Author

CI note: the full pytest job failure is unrelated to this PR. It fails only in tests/test_fastapi_v1_dashboard.py under FastAPI 0.137 route internals, matching the compatibility issue fixed by #8783. The targeted tool permission tests and all other checks for this PR pass.

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:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] permission-wrapped FunctionTool run() tools return no callable handler

1 participant