Class ToolAvailability

java.lang.Object
com.axelor.ai.tool.ToolAvailability

public final class ToolAvailability extends Object
Whether a tool may run, given who is on the other end of the turn.

Shared by the two places that must agree: AgentResolverPlugin decides what the model is allowed to see, and ToolExecutorPlugin decides what it is allowed to execute. Letting these drift is what turns an unusable tool into a stalled turn.

  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    deniedToProgrammatic(AiTool tool, SystemTool<?> systemTool)
    Whether a programmatic request -- one with no session behind it -- must be denied this tool.
    static boolean
    mutates(AiTool tool, SystemTool<?> systemTool)
    Whether a tool could change data, and so must be withheld from a programmatic request.
    static boolean
    needsApproval(AiTool tool, SystemTool<?> systemTool, boolean foreignContext)
    Whether a tool needs a human to approve it before it runs.
    static boolean
    Whether a trial run offers a tool: not one the browser runs, since a trial has no browser, nor try_agent, since a trial does not start another.
    static boolean
    requiresUser(AiTool tool, SystemTool<?> systemTool)
    Whether a tool needs a person, and so can never complete on a programmatic request (a workflow <agent> node, a screening call — anything with no session to answer).
    static boolean
    runsInTrial(AiTool tool, SystemTool<?> systemTool)
    Whether a trial run actually runs a tool, its changes undone after the call: a system tool that a rollback undoes.
    static boolean
    Whether a tool's work is an external network call, and so must not hold a database connection while it waits.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • needsApproval

      public static boolean needsApproval(AiTool tool, SystemTool<?> systemTool, boolean foreignContext)
      Whether a tool needs a human to approve it before it runs. System tool safety can force approval off (ToolSafety.READ_ONLY) or on (ToolSafety.DESTRUCTIVE); regular write tools and non-system tools use the requiresApproval flag on the tool configuration. With foreign text in the prompt every tool that may mutate requires approval — WRITE system tools, and all SCRIPT/HTTP/ACTION tools, which carry no safety classification and must be assumed mutating.
      Parameters:
      tool - the configured tool
      systemTool - the resolved system tool for tool, or null for non-system tools
      foreignContext - whether another member's text sits in the prompt
    • requiresUser

      public static boolean requiresUser(AiTool tool, SystemTool<?> systemTool)
      Whether a tool needs a person, and so can never complete on a programmatic request (a workflow <agent> node, a screening call — anything with no session to answer). Two kinds qualify: CLIENT tools, which execute in the browser and have none to execute in; and anything needsApproval(com.axelor.ai.db.AiTool, com.axelor.ai.tool.system.SystemTool<?>, boolean) flags, since nobody is there to grant it.

      Such a tool must be withheld from the model rather than offered and then refused: a model that calls it cannot be answered, and a turn that cannot be answered is a turn that stops mid-reasoning.

      Tool type is deliberately not the test beyond CLIENT. An MCP tool is a server-side network call needing nobody, and synchronization sets requiresApproval on create only — clearing it afterwards is the administrator's decision to make, and is honoured here.

      Parameters:
      tool - the configured tool
      systemTool - the resolved system tool for tool, or null for non-system tools
    • mutates

      public static boolean mutates(AiTool tool, SystemTool<?> systemTool)
      Whether a tool could change data, and so must be withheld from a programmatic request.

      A workflow <agent> node exists to answer a question the workflow then acts on: the workflow performs the persistence, not the agent. That was only ever a sentence in the prompt -- and record text interpolated into the same prompt is free to argue with a sentence. This makes it a boundary the model cannot be talked out of.

      Only a READ_ONLY system tool is known not to mutate. Everything else is assumed to: WRITE and DESTRUCTIVE say as much, and SCRIPT/HTTP/ACTION/MCP carry no safety classification at all, so there is nothing to go on but the name. Assuming the worst of an unclassified tool is the only safe direction for a boundary to fail in -- the cost is an agent answering with fewer tools, which is recoverable; the cost of the other direction is not.

      Parameters:
      tool - the configured tool
      systemTool - the resolved system tool for tool, or null for non-system tools
    • runsOutsideTransaction

      public static boolean runsOutsideTransaction(AiTool tool, SystemTool<?> systemTool)
      Whether a tool's work is an external network call, and so must not hold a database connection while it waits.

      An HTTP tool reads its own definition and sends a request; an MCP tool talks to a remote server. Neither touches data of its own, so neither has anything to commit -- while a slow endpoint would otherwise keep a connection checked out for as long as it takes to answer. Every other type may write, through a repository, a script or an action, and keeps the transaction that makes those writes atomic with the rest of the call — unless it is a system tool that opens its own (SystemTool.runsOutsideTransaction()).

      Parameters:
      tool - the configured tool
      systemTool - the resolved system tool for tool, or null for non-system tools
    • deniedToProgrammatic

      public static boolean deniedToProgrammatic(AiTool tool, SystemTool<?> systemTool)
      Whether a programmatic request -- one with no session behind it -- must be denied this tool.

      Two independent reasons, and either is enough: nobody is there to run or approve it, or it could write and a programmatic caller has no business writing through an agent.

    • offeredInTrial

      public static boolean offeredInTrial(AiTool tool)
      Whether a trial run offers a tool: not one the browser runs, since a trial has no browser, nor try_agent, since a trial does not start another.
    • runsInTrial

      public static boolean runsInTrial(AiTool tool, SystemTool<?> systemTool)
      Whether a trial run actually runs a tool, its changes undone after the call: a system tool that a rollback undoes. Any other may reach what a rollback does not, and is not run.