Record Class DynamicToolMethod

java.lang.Object
java.lang.Record
com.tnsai.tools.method.DynamicToolMethod
Record Components:
name - the LLM-facing tool name
description - human-readable description for the LLM tool catalog
idempotent - hint for the retry / fallback layer
requiresConfirmation - whether dispatch should be gated by an approval filter (AGENT-V006); defaults to false via of(java.lang.String, java.lang.String, boolean, java.util.Map<java.lang.String, java.lang.Object>, com.tnsai.tools.method.DynamicToolMethod.Handler)
keywords - framework-discovery keywords (not LLM-facing); never null
parametersSchema - pre-built JSON Schema fragment (the parameters object that goes into function.parameters for OpenAI or input_schema for Anthropic)
handler - dispatch callback — receives the LLM's argument map verbatim
All Implemented Interfaces:
ToolMethod

public record DynamicToolMethod(String name, String description, boolean idempotent, boolean requiresConfirmation, List<String> keywords, Map<String,Object> parametersSchema, DynamicToolMethod.Handler handler, ExecutionRule execution) extends Record implements ToolMethod
A ToolMethod whose name, description, JSON-Schema, and dispatch handler are all supplied at construction time — no @Tool annotation, no reflected Method.

Use case: a tool whose identity is only known at runtime. The canonical example is McpProxyTool (in tnsai-server): each MCP server discovered through a CLI WebSocket exposes its own tool catalog with names like github_create_issue or filesystem_read_file. The framework cannot know these names at compile time, so it cannot annotate them with @Tool.

The DynamicToolMethod.Handler callback receives the LLM's argument map verbatim and returns whatever the proxy resolves to. The dispatcher does no reflection here — coercion is the handler's responsibility (which makes sense: a proxy receives a JSON-like map and forwards it as-is to a remote endpoint).

parameters() returns an empty list because dynamic tools advertise their shape through parametersSchema() directly — a pre-built JSON Schema fragment supplied by the registrant (typically derived from the MCP server's inputSchema).

Safety / discovery metadata (TNS-556)

requiresConfirmation() brings the dynamic path to parity with @Tool(requiresConfirmation=true) for the AGENT-V006 approval gate: a dynamic tool can now declare it needs confirmation, and AgentBuilder's confirmation scan + any ToolCallFilter see it (previously only annotated @Tool POJOs were scanned, so dynamic / MCP tools silently escaped the approval check). keywords() carries framework-discovery keywords (not LLM-facing), as on the static path. (The sideEffect/idempotencyHint fields from @Tool are intentionally not modelled here — no runtime consumer reads them off a ToolMethod today, so they would be no-op surface; deferred until a reader exists.)
Since:
0.7.0 (RFC #188 closeout — replaced the Tool interface + McpProxyTool implements-Tool path with a typed dynamic-method registration); requiresConfirmation / keywords added in 0.11.1 (TNS-556)
  • Constructor Details

    • DynamicToolMethod

      public DynamicToolMethod(String name, String description, boolean idempotent, boolean requiresConfirmation, List<String> keywords, Map<String,Object> parametersSchema, DynamicToolMethod.Handler handler)
      Registrations without an execution policy retain existing security behavior.
    • DynamicToolMethod

      public DynamicToolMethod(String name, String description, boolean idempotent, boolean requiresConfirmation, List<String> keywords, Map<String,Object> parametersSchema, DynamicToolMethod.Handler handler, ExecutionRule execution)
      Creates an instance of a DynamicToolMethod record class.
      Parameters:
      name - the value for the name record component
      description - the value for the description record component
      idempotent - the value for the idempotent record component
      requiresConfirmation - the value for the requiresConfirmation record component
      keywords - the value for the keywords record component
      parametersSchema - the value for the parametersSchema record component
      handler - the value for the handler record component
      execution - the value for the execution record component
    • DynamicToolMethod

      public DynamicToolMethod(String name, String description, boolean idempotent, Map<String,Object> parametersSchema, DynamicToolMethod.Handler handler)
      Backward-compatible 5-arg constructor (pre-0.11.1 signature). Delegates to the canonical constructor with requiresConfirmation=false and empty keywords so existing new DynamicToolMethod(name, desc, idempotent, schema, handler) call sites keep compiling unchanged.
  • Method Details

    • of

      public static DynamicToolMethod of(String name, String description, boolean idempotent, Map<String,Object> parametersSchema, DynamicToolMethod.Handler handler)
      Backward-compatible factory matching the pre-0.11.1 5-arg shape — defaults the safety/discovery fields to the safe "no claim" values (requiresConfirmation=false, empty keywords), so existing callers behave exactly as before. Equivalent to the 5-arg constructor.
    • builder

      public static DynamicToolMethod.Builder builder(String name)
    • parameters

      public List<ToolParameter> parameters()
      Description copied from interface: ToolMethod
      Parameter metadata in declaration order. StaticToolMethod returns the reflected @ToolParam list; DynamicToolMethod returns empty since dynamic tools advertise their shape through ToolMethod.parametersSchema() directly.
      Specified by:
      parameters in interface ToolMethod
    • invoke

      public Object invoke(Map<String,Object> args, com.fasterxml.jackson.databind.ObjectMapper mapper) throws Exception
      Description copied from interface: ToolMethod
      Dispatch a tool call.
      Specified by:
      invoke in interface ToolMethod
      Parameters:
      args - the LLM's argument map (Jackson-friendly: String / Number / Boolean / List / Map / null)
      mapper - a Jackson ObjectMapper for type coercion (used by StaticToolMethod to convert JSON values to the parameter's static Java type; ignored by DynamicToolMethod)
      Returns:
      the typed result for the caller to JSON-serialise back to the LLM
      Throws:
      Exception - any exception thrown by the underlying tool body
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. Reference components are compared with Objects::equals(Object,Object); primitive components are compared with '=='.
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • name

      public String name()
      Returns the value of the name record component.
      Specified by:
      name in interface ToolMethod
      Returns:
      the value of the name record component
    • description

      public String description()
      Returns the value of the description record component.
      Specified by:
      description in interface ToolMethod
      Returns:
      the value of the description record component
    • idempotent

      public boolean idempotent()
      Returns the value of the idempotent record component.
      Specified by:
      idempotent in interface ToolMethod
      Returns:
      the value of the idempotent record component
    • requiresConfirmation

      public boolean requiresConfirmation()
      Returns the value of the requiresConfirmation record component.
      Specified by:
      requiresConfirmation in interface ToolMethod
      Returns:
      the value of the requiresConfirmation record component
    • keywords

      public List<String> keywords()
      Returns the value of the keywords record component.
      Specified by:
      keywords in interface ToolMethod
      Returns:
      the value of the keywords record component
    • parametersSchema

      public Map<String,Object> parametersSchema()
      Returns the value of the parametersSchema record component.
      Specified by:
      parametersSchema in interface ToolMethod
      Returns:
      the value of the parametersSchema record component
    • handler

      public DynamicToolMethod.Handler handler()
      Returns the value of the handler record component.
      Returns:
      the value of the handler record component
    • execution

      public ExecutionRule execution()
      Returns the value of the execution record component.
      Returns:
      the value of the execution record component