Record Class DynamicToolMethod
- Record Components:
name- the LLM-facing tool namedescription- human-readable description for the LLM tool catalogidempotent- hint for the retry / fallback layerrequiresConfirmation- whether dispatch should be gated by an approval filter (AGENT-V006); defaults tofalseviaof(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 nullparametersSchema- pre-built JSON Schema fragment (theparametersobject that goes intofunction.parametersfor OpenAI orinput_schemafor Anthropic)handler- dispatch callback — receives the LLM's argument map verbatim
- All Implemented Interfaces:
ToolMethod
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
Toolinterface +McpProxyToolimplements-Tool path with a typed dynamic-method registration);requiresConfirmation/keywordsadded in 0.11.1 (TNS-556)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classFluent builder — the ergonomic way to set the safety/discovery fields (TNS-556).static interfaceDispatch callback for aDynamicToolMethod. -
Constructor Summary
ConstructorsConstructorDescriptionDynamicToolMethod(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(String name, String description, boolean idempotent, boolean requiresConfirmation, List<String> keywords, Map<String, Object> parametersSchema, DynamicToolMethod.Handler handler, ExecutionRule execution) Creates an instance of aDynamicToolMethodrecord class.DynamicToolMethod(String name, String description, boolean idempotent, Map<String, Object> parametersSchema, DynamicToolMethod.Handler handler) Backward-compatible 5-arg constructor (pre-0.11.1 signature). -
Method Summary
Modifier and TypeMethodDescriptionstatic DynamicToolMethod.BuilderReturns the value of thedescriptionrecord component.final booleanIndicates whether some other object is "equal to" this one.Returns the value of theexecutionrecord component.handler()Returns the value of thehandlerrecord component.final inthashCode()Returns a hash code value for this object.booleanReturns the value of theidempotentrecord component.Dispatch a tool call.keywords()Returns the value of thekeywordsrecord component.name()Returns the value of thenamerecord component.static DynamicToolMethodof(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, emptykeywords), so existing callers behave exactly as before.Parameter metadata in declaration order.Returns the value of theparametersSchemarecord component.booleanReturns the value of therequiresConfirmationrecord component.final StringtoString()Returns a string representation of this record class.
-
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 aDynamicToolMethodrecord class.- Parameters:
name- the value for thenamerecord componentdescription- the value for thedescriptionrecord componentidempotent- the value for theidempotentrecord componentrequiresConfirmation- the value for therequiresConfirmationrecord componentkeywords- the value for thekeywordsrecord componentparametersSchema- the value for theparametersSchemarecord componenthandler- the value for thehandlerrecord componentexecution- the value for theexecutionrecord 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 withrequiresConfirmation=falseand empty keywords so existingnew 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, emptykeywords), so existing callers behave exactly as before. Equivalent to the 5-arg constructor. -
builder
-
parameters
Description copied from interface:ToolMethodParameter metadata in declaration order.StaticToolMethodreturns the reflected@ToolParamlist;DynamicToolMethodreturnsemptysince dynamic tools advertise their shape throughToolMethod.parametersSchema()directly.- Specified by:
parametersin interfaceToolMethod
-
invoke
public Object invoke(Map<String, Object> args, com.fasterxml.jackson.databind.ObjectMapper mapper) throws ExceptionDescription copied from interface:ToolMethodDispatch a tool call.- Specified by:
invokein interfaceToolMethod- Parameters:
args- the LLM's argument map (Jackson-friendly:String / Number / Boolean / List / Map / null)mapper- a JacksonObjectMapperfor type coercion (used byStaticToolMethodto convert JSON values to the parameter's static Java type; ignored byDynamicToolMethod)- 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
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. -
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. -
equals
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 withObjects::equals(Object,Object); primitive components are compared with '=='. -
name
Returns the value of thenamerecord component.- Specified by:
namein interfaceToolMethod- Returns:
- the value of the
namerecord component
-
description
Returns the value of thedescriptionrecord component.- Specified by:
descriptionin interfaceToolMethod- Returns:
- the value of the
descriptionrecord component
-
idempotent
public boolean idempotent()Returns the value of theidempotentrecord component.- Specified by:
idempotentin interfaceToolMethod- Returns:
- the value of the
idempotentrecord component
-
requiresConfirmation
public boolean requiresConfirmation()Returns the value of therequiresConfirmationrecord component.- Specified by:
requiresConfirmationin interfaceToolMethod- Returns:
- the value of the
requiresConfirmationrecord component
-
keywords
Returns the value of thekeywordsrecord component.- Specified by:
keywordsin interfaceToolMethod- Returns:
- the value of the
keywordsrecord component
-
parametersSchema
Returns the value of theparametersSchemarecord component.- Specified by:
parametersSchemain interfaceToolMethod- Returns:
- the value of the
parametersSchemarecord component
-
handler
Returns the value of thehandlerrecord component.- Returns:
- the value of the
handlerrecord component
-
execution
Returns the value of theexecutionrecord component.- Returns:
- the value of the
executionrecord component
-