Skip to content

feat(tools): Add feasible/annotated tool filtering based on agent-state predicates#168

Open
yashhzd wants to merge 2 commits intomesa:mainfrom
yashhzd:feat/feasible-tools-filter-148
Open

feat(tools): Add feasible/annotated tool filtering based on agent-state predicates#168
yashhzd wants to merge 2 commits intomesa:mainfrom
yashhzd:feat/feasible-tools-filter-148

Conversation

@yashhzd
Copy link
Contributor

@yashhzd yashhzd commented Mar 6, 2026

Summary

Closes #148.

Adds support for conditionally filtering tools based on agent-state predicates, so reasoning strategies can present only feasible tools to the LLM (or annotate infeasible ones for planner awareness).

Changes

@tool(requires=...) decorator parameter

  • New optional requires keyword on @tool: a callable (agent) -> bool that returns True when the tool is usable by the given agent.
  • The predicate is stored as fn.__tool_requires__ on the decorated function.

ToolManager methods

  • _is_tool_feasible(fn, agent) — checks the __tool_requires__ predicate; returns True when no predicate is set or when it passes, False on failure or exception.
  • get_feasible_tools_schema(agent, selected_tools=None) — returns schemas only for tools whose preconditions are satisfied.
  • get_annotated_tools_schema(agent, selected_tools=None) — returns all tool schemas with added available (bool) and unavailable_reason (str | None) keys, so planners can reason about currently-infeasible tools.

Built-in tool predicates

  • _has_grid_and_position(agent) — applied to move_one_step and teleport_to_location.
  • _has_other_agents(agent) — applied to speak_to.

Tests

  • 8 new tests in tests/test_tools/test_feasible_tools.py covering:
    • Filtering infeasible tools
    • Tools without requires always included
    • Predicate receives correct agent state
    • selected_tools interaction
    • Exception in predicate treated as infeasible
    • Annotated schema correctness (available, unavailable_reason)

Backward Compatibility

  • requires defaults to None, so all existing @tool decorations are unaffected.
  • get_all_tools_schema() remains unchanged; the new methods are additive.
  • Reasoning strategies can adopt the new methods at their own pace.

…a#148)

ToolManager.get_all_tools_schema() exposes every registered tool to
the LLM regardless of whether the tool is actually usable by the
agent.  A wolf with 0 energy still sees move_one_step; an agent
with no grid still sees teleport_to_location.

Add a requires predicate system:

- @tool(requires=fn) accepts an (agent) -> bool predicate that
  checks whether the tool's preconditions are met
- ToolManager.get_feasible_tools_schema(agent) returns only tools
  whose requires predicate passes (or tools without a predicate)
- ToolManager.get_annotated_tools_schema(agent) returns all tools
  with available/unavailable_reason annotations for planner use

Apply requires predicates to built-in tools:
- move_one_step, teleport_to_location: require grid/space + position
- speak_to: requires at least one other agent

The existing get_all_tools_schema() is unchanged for full backward
compatibility.
@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.15%. Comparing base (4c0549e) to head (caf2fe6).
⚠️ Report is 19 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #168      +/-   ##
==========================================
+ Coverage   90.08%   91.15%   +1.06%     
==========================================
  Files          19       19              
  Lines        1503     1582      +79     
==========================================
+ Hits         1354     1442      +88     
+ Misses        149      140       -9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 6, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d19e8c3-47c3-4214-91df-f58f5b57ed82

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Add direct tests for _has_grid_and_position and _has_other_agents
predicate functions covering all branches: no grid/space, grid with
position, cell coordinate, no position, and agent isolation.
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.

ToolManager.get_all_tools_schema() exposes every tool to the LLM regardless of agent state

1 participant