Preprocessors are the explicit, owner-configured transforms in
PiToolOwnerAdapterOptions.preprocessors. Configure only transforms that are
semantically safe for your tool — the pipeline deliberately does not guess
aliases, fuzzily rename keys, or delete unknown fields. Wrapped tools already
get bounded envelope recovery (stringified JSON, singleton envelopes) and
schema-located repairs (invalid optional null, string-where-array) without
any configuration.
JSON-Pointer-like paths addressing one configured location:
| Selector | Meaning |
|---|---|
"/path" |
field path at the root |
"/edits/*/oldText" |
field oldText in every item of array edits |
"" |
the root value itself |
Pointer escapes: ~0 = ~, ~1 = / in field names.
| Kind | Intended use |
|---|---|
alias |
Move an explicitly listed alternative key to its canonical location (file_path → path). |
filesystem-path |
Unwrap a markdown auto-link in one path string. |
filesystem-path-array |
Apply path cleanup to string items in one array. |
string-or-array |
Wrap one configured string as a one-item array. |
scalar |
Convert a configured string/number/boolean scalar to the declared scalarType. |
anchor-bleed |
Strip model-gated ^/$ artifacts from one configured string. |
grammar-tokens |
Strip model-gated <arg_key>/<arg_value> tokens at configured keys/values. |
structural |
Owner-supplied shape transformation with a stable ruleId and note. |
alias options: guard accepted value types with
accepts: "string" | "number" | "boolean" | "array" | "object". By default an
existing canonical value wins; set emptyEquivalentToMissing: true only when
an empty canonical value is invalid or genuinely means "not supplied".
Model-gated kinds (anchor-bleed, grammar-tokens) require both a
modelId in the options and matching modelFamilies regexes on the entry:
{
policy: "adaptive",
modelId: "provider/model-id",
preprocessors: [{
kind: "anchor-bleed",
selector: "/path",
modelFamilies: [/kimi-k2/i, /glm/i],
}],
}Options are captured at wrap time. If the tool must follow model changes
mid-session, re-register with the new model ID or use the pure-core API from
an owner-managed prepareArguments.
Never apply path cleanup to arbitrary content, and never apply anchor cleanup
to real regex fields (a leading ^ there may be intentional syntax).
| Profile | Behavior |
|---|---|
conservative |
Bounded lossless envelope recovery, exact configured preprocessing, schema-guided repair; observes model-gated valid-value artifacts without mutating them. |
adaptive (default) |
Adds schema-validated truncated-object completion and configured model-gated value cleanup. |
recover |
Same tool-argument behavior as adaptive; additionally enables gated assistant-text grammar promotion only when the installable extension handles message_end — the adapter itself never registers grammar hooks. |
- Every mutation carries a stable rule ID and a model-facing note.
- A
repairedoutcome always means the final arguments passed the supplied schema; strictly valid input is returned untouched by reference. - Unrecognized
kinds are ignored (no mutation, no error, no claimed change) and the result is still schema-validated — version skew degrades safely. - Unrepairable input throws
UnrepairableToolInputErrorwith a model-readable retry message (fail closed) unlessunrepairable: "passthrough"is explicitly set.
Keep an existing owner hook on the definition; the adapter chains it after envelope recovery and before configured preprocessors and schema repair. The shim should perform only compatibility work belonging to that tool.