Wymcp.Tool.Schema (Wymcp v0.2.2)

View Source

Builds the JSON Schema inputSchema for Wymcp tools.

One shape: the action field lists the declared action names as an enum whose description carries the action summaries, one per line, and data is a bare object. build/1 and action_summaries/1 render those summaries from one private function, so the enum description and the help index cannot drift. The newline separator stays unambiguous because Wymcp.Tool.validate_actions!/1 — run at every moment a tool's schemas are validated — rejects a newline in an action's name or its description, the two halves a summary joins. Wymcp.Tool's generated input_schema/0 is the only caller of build/1.

Both public functions take the tool module, not an actions map, and obtain the schemas themselves through Wymcp.Tool.fetch_action_schemas!/1 — so there is no way to hand this module a map that no validator has seen, and the direct schema.description read below needs no check of its own. Each obtains once and hands the map to a private function: obtaining twice on one path could publish an action enum that disagrees with its own summaries, for a tool whose Wymcp.Tool.actions/0 varies between calls.

The key set is closed and said so out loud: the root carries additionalProperties: false, which is the server stating its contract in tools/list so a schema-aware client can catch a misspelled key before it sends. Enforcement is not this schema's job — argument validation checks structure only, and a dispatch gate answers a stray key in the tool dialect, naming the key and pointing at help (see "Dispatch errors and self-correction" in Wymcp.Tool). The declaration is the root's alone: data stays a bare object, so a tool that nests free-form structure under it is unaffected.

Per-action constraints are deliberately not encoded here: :required and :required_one_of are enforced at dispatch by Wymcp.Tool, and the full per-action schemas are surfaced on demand by Wymcp.Help. Property values (types, formats) are not validated by the framework at all — a tool that needs value guarantees checks them in run_action/3. This keeps the tools/list payload compact; agents act from the action summaries and pay for a tool's full schemas only when they ask.

Summary

Functions

An action summary is one action's name joined to its description as "<action>: <description>". Returns one summary per action of module, sorted by action name.

Types

json_schema()

@type json_schema() :: %{required(String.t()) => term()}

Functions

action_summaries(module)

An action summary is one action's name joined to its description as "<action>: <description>". Returns one summary per action of module, sorted by action name.

What the help tool's server index renders from. build/1 renders the tools/list action description from the same private function rather than from this one, so a change made here alone reaches the index only.

Example

Given a tool whose Wymcp.Tool.actions/0 returns

%{
  get: %{description: "Get a widget", properties: %{}},
  create: %{description: "Create a widget", properties: %{}}
}

the summaries are

["create: Create a widget", "get: Get a widget"]

build(module)