Class ActionParams

java.lang.Object
com.tnsai.metadata.ActionParams

public final class ActionParams extends Object
Static helpers for safely picking values out of an action's Map<String, Object> parameters bag.

Exists to centralise the deceptively-tricky "pick the action's primary input value" logic that several executors and resolvers need (LLM tool dispatch, RAG retrieval query selection, future decorator-stack work). The naive parameters.values().iterator().next() pattern is a real footgun:

  • HashMap iteration order is deterministic per JVM but not user-declared — different hash codes produce different "first" values.
  • Map.of(...) factories deliberately randomise iteration order per JVM start (since Java 9) to discourage exactly this kind of order-dependent code. Two runs of the same action could pick different parameters as the "primary" one.
  • .toString() on the first value NPEs when the value is null; throws NoSuchElementException on an empty map.

The firstStringValueInDeclarationOrder(com.tnsai.metadata.ActionMetadata, java.util.Map<java.lang.String, java.lang.Object>) helper picks the first String-typed parameter in declaration order (from

invalid reference
ActionMetadata#getParameters()
) that has a non-blank value, falling back to a non-blank scan of the map if no declared params surface a hit. This matches the behaviour users actually expect from "give me the action's input".
Since:
0.5.4 (issue #177 follow-up — eliminate non-deterministic parameter-iteration smell)
  • Method Details

    • firstStringValueInDeclarationOrder

      public static Optional<String> firstStringValueInDeclarationOrder(ActionMetadata action, Map<String,Object> parameters)
      Returns the value of the first String-typed parameter in declaration order whose entry in parameters is a non-blank String. Falls back to any non-blank String value in the map if no declared param surfaces a hit (covers callers that build ActionMetadata without surfacing ParamSpec information).
      Parameters:
      action - the action being dispatched
      parameters - the working-parameter map
      Returns:
      the picked value, or empty if no usable String exists
    • parameterNames

      public static List<String> parameterNames(ActionMetadata action)
      Returns the declared parameter names of action, in declaration order.

      Callers that resolve a parameter by name need this to tell "the caller named something that does not exist", which is a configuration fault, from "the parameter exists but carries no usable value on this call", which is not. The list is also what makes the resulting error message actionable — naming the alternatives beats reporting only what was missing.

      Parameters:
      action - the action being dispatched, may be null
      Returns:
      declared names in declaration order, empty when the action surfaces no ParamSpec metadata
      Since:
      0.14.0
    • stringValue

      public static Optional<String> stringValue(Map<String,Object> parameters, String name)
      Returns the value bound to name when it is a non-blank String.

      Absent, null, blank and non-String values are all reported the same way — as empty. A caller resolving a named parameter has already established that the name is valid; what is left is whether this particular call supplied something usable, and every way of failing that test leads to the same handling.

      Parameters:
      parameters - the working-parameter map, may be null
      name - the declared parameter name to read
      Returns:
      the value, or empty when it is missing or unusable
      Since:
      0.14.0