Converts BB command argument definitions into Peri schemas suitable for
Anubis.Server.Frame.register_tool/3.
Anubis takes the Peri schema we hand it, validates incoming tool calls against it, and re-renders it as JSON Schema on the wire. So one conversion suffices for both validation and discovery.
BB types map to Peri types as follows:
:integer | :pos_integer | :non_neg_integer -> :integer
:float | :number -> :float
:string -> :string
:boolean -> :boolean
:atom -> :atom
:map | {:map, fields} -> :map
:keyword_list -> :keyword
:any -> :any
module / unknown -> :any
Summary
Functions
Pre-process incoming params before Peri validation.
Build a Peri field value for a single argument, applying required and
default wrappers and a description meta tag where set.
Build a Peri schema (map keyed by argument name) for a command's arguments.
Translate MCP-visible command params back to the command's original BB goal.
Functions
@spec flatten_nested_params(BB.Dsl.Command.t(), map()) :: map()
Pre-process incoming params before Peri validation.
Some MCP clients interpret a flat property name like "target.x" as a nested
path and send %{"target" => %{"x" => ...}} instead of %{"target.x" => ...}.
We advertise the flat (dotted) form deliberately — nested object schemas are
poorly supported by some clients — so we flatten any nested object back to
the dotted form here before Peri's schema validator sees them.
Also coerces JSON whole numbers (0, 1) to floats for fields whose schema
type is :float — JSON has no syntactic distinction between integer and
float zero, but Peri's :float validator rejects integers.
@spec for_argument(BB.Dsl.Command.Argument.t()) :: term()
Build a Peri field value for a single argument, applying required and
default wrappers and a description meta tag where set.
@spec for_command(BB.Dsl.Command.t()) :: map()
Build a Peri schema (map keyed by argument name) for a command's arguments.
@spec to_goal(BB.Dsl.Command.t(), map()) :: map()
Translate MCP-visible command params back to the command's original BB goal.