Noizu.MCP.Description (Noizu MCP v0.1.6)

Copy Markdown View Source

A tailored description: one string chosen per render context, with gap-fill interpolation for verbosity levels that no variant covers and — for weak harnesses/models — per-runner/model overrides (spec §3).

Verbosity variants (spec §2)

Anywhere a description string is accepted today — a tool's description:, a toolkit @mcp description:, a field ... description: — a variant list is also accepted:

description: [
  {{:verbosity, {2, 3}}, "Medium description."},
  {{:verbosity, 0},      "Terse."},
  default: "Definitive fallback text"
]

A bare string (description: "just text") is unchanged and covers every level.

Keys

  • {:verbosity, n} — a single level n
  • {:verbosity, {lo, hi}} — an inclusive range
  • {:verbosity, [n, ...]} — an explicit set of levels
  • default: "text" — the definitive/fallback string, used when nothing more specific applies
  • default_verbosity: n — the annotation-level default verbosity, applied when a render context supplies no explicit verbosity

The verbosity domain is 0–9 (0 = tersest). Levels, range bounds, and set members outside that domain are a compile error, as are malformed keys and two entries covering the same exact level.

Deliberate deviation from the design spec. The spec sketched the annotation-level default as default: [{:verbosity, 3}], overloading the default: key (fallback text vs. default-verbosity setting). This module splits them: default: is always the fallback text; default_verbosity: is the default level. Flagged for review.

Named variants + runner/model rules (spec §3)

Alongside description:, three sibling options — accepted on use Noizu.MCP.Server.Tool, @mcp, and field — build a tailored description without forking the tool. from_opts/2 compiles them together:

description:   "definitive fallback",         # the default text
descriptions:  [foo_bar: "…", "hippo-5": "…", codex_foobar: "…"],
verbosity_map: [{{0, 5}, :foo_bar}],          # verbosity → named variant
runners: [
  {{:grok, :*},              [{{:verbosity, {0, 5}}, :"hippo-5"}]},
  {{:codex, [:spark, :"5.4"]}, [default: :codex_foobar]}
]
  • descriptions: — a keyword list of tag: "text" named variants. Tags may be atoms or strings; they are stored normalized to strings.
  • verbosity_map:[{verbosity_spec, tag}, ...], mapping a verbosity selector (int / {lo, hi} / [levels]) to a named variant.
  • runners:[{{provider, model_matcher}, rules}, ...]. provider is an atom (or :* wildcard); model_matcher is :*, an exact atom/string, or a list of atoms/strings (membership). rules is a keyword-ish list mixing {{:verbosity, spec}, tag} entries and a default: tag.

Every tag referenced by verbosity_map:/runners: must be declared in descriptions:, and matchers must be well-formed — both are validated at compile time (an ArgumentError, surfaced as a compile error at the DSL call site).

Resolution

resolve/2 maps a normalized description and a Noizu.MCP.RenderCtx to a concrete string (or nil). Precedence (spec §0), first match wins:

  1. the most specific matching runner rule — its own verbosity → tag map (same gap-fill), falling back to the rule's default: tag;
  2. the tool/field-level verbosity_map (verbosity → tag, gap-filled);
  3. the inline levels variants (verbosity → text, gap-filled — the §2 path);
  4. the default: fallback text (or nil).

Runner specificity (most specific wins; ties break toward declaration order): the model matcher dominates the provider matcher — exact model (2) > model-in-list (1) > :* (0); then provider exact (1) > :* (0). Model and provider comparisons are insensitive to atom-vs-string representation, so "5.4" matches :"5.4".

For an uncovered verbosity level, gap-fill picks the entry whose nearest covered level is the smallest absolute distance away; ties prefer the lower level ("left preference"). Worked examples (from the spec): defined {2,3} and 0, request 10; defined 3 and 9, request 89, 53, 63.

Summary

Types

A compiled runner rule. provider is an atom or :*; model is :any, {:exact, normalized}, or {:list, [normalized]}; levels maps a verbosity level to a variant tag (gap-filled); default_tag is the rule's fallback tag.

t()

Functions

Normalize a plain description: value into nil, a bare string, or a %Description{}.

Compile a DSL option set into a description, combining description: with the named-variant options descriptions:, verbosity_map:, and runners:.

Resolve a description against a render context, yielding a concrete string or nil.

Types

input()

@type input() :: nil | String.t() | [variant_entry()] | t()

runner_rule()

@type runner_rule() :: %{
  provider: atom() | String.t(),
  model: :any | {:exact, String.t()} | {:list, [String.t()]},
  levels: %{optional(0..9) => String.t()},
  default_tag: String.t() | nil
}

A compiled runner rule. provider is an atom or :*; model is :any, {:exact, normalized}, or {:list, [normalized]}; levels maps a verbosity level to a variant tag (gap-filled); default_tag is the rule's fallback tag.

t()

@type t() :: %Noizu.MCP.Description{
  default: String.t() | nil,
  default_verbosity: 0..9 | nil,
  levels: %{optional(0..9) => String.t()},
  runners: [runner_rule()],
  variants: %{optional(String.t()) => String.t()},
  verbosity_map: %{optional(0..9) => String.t()}
}

variant_entry()

@type variant_entry() ::
  {variant_key(), String.t()}
  | {:default, String.t()}
  | {:default_verbosity, integer()}

variant_key()

@type variant_key() ::
  {:verbosity, integer()}
  | {:verbosity, {integer(), integer()}}
  | {:verbosity, [integer()]}

Functions

compile(input, context \\ "description")

@spec compile(input(), String.t()) :: nil | String.t() | t()

Normalize a plain description: value into nil, a bare string, or a %Description{}.

Bare strings pass through unchanged (so plain-string tools stay byte-identical). A verbosity variant list compiles to a struct, validating the domain and rejecting malformed keys or duplicate level coverage. context names the owning tool/field for error messages.

For the named-variant / runner-rule form, use from_opts/2.

from_opts(opts, context)

@spec from_opts(
  keyword(),
  String.t()
) :: nil | String.t() | t()

Compile a DSL option set into a description, combining description: with the named-variant options descriptions:, verbosity_map:, and runners:.

When none of the three sibling options are present this is exactly compile(opts[:description], context) — plain strings and §2 variant lists are unchanged. When any is present, the description: value becomes the base (a bare string becomes the default: text; a §2 variant list contributes its levels), then named variants, the verbosity map, and runner rules are layered on and every referenced tag is validated.

resolve(text, ctx)

@spec resolve(nil | String.t() | t(), Noizu.MCP.RenderCtx.t()) :: String.t() | nil

Resolve a description against a render context, yielding a concrete string or nil.

Precedence for the effective level: the context's explicit verbosity, then the description's default_verbosity, then the context's defaults chain, then the built-in 5; the result is clamped to 0..9.

Variant precedence (spec §0, first match wins): the most specific matching runner rule; then verbosity_map (verbosity → tag); then inline levels (verbosity → text); then the default: fallback text (or nil).