fix: render tool schemas with root-level anyOf/oneOf composition
A tool's `inputSchema` may carry composition keywords at its root — the 2026-07-28 revision makes this explicit — but both form builders enumerate the root's `properties` and nothing else. A schema keeping its fields on `allOf`/`oneOf`/`anyOf` branches therefore rendered no controls at all: no branch picker, no fields, not even the raw-JSON fallback a union-typed *property* falls back to, so the tool could only be called with empty arguments. Adds `core/json/rootUnion.ts`, one flattening shared by all three clients so they cannot drift on which schemas they can render: - `allOf` is merged unconditionally (conjunctive — there is no choice to present), a root `oneOf`/`anyOf` is returned as branches. - Web `SchemaForm` renders a Variant picker above the fields and prunes the outgoing branch's values on a switch, since they are no longer visible and would describe a shape the call is not making. - TUI `schemaToForm` gives each branch its own section with optional fields — ink-form is static, and only one alternative applies to a call. - `convertToolParameters` looks through the branches, so a CLI `--tool-arg` is typed by the schema that declares it rather than sent as a string. Required-field gating asks whether *any* branch is satisfied, which is selection-independent and never blocks arguments the schema accepts. A `const` is seeded like a `default` and rendered read-only: it admits exactly one value, so anything else the user could type produces a rejected call. Adds a `root-union-schemas-http.json` showcase server. Closes #2123 Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
ca2846de28
commit
5933162dd0
1 changed files with 1259 additions and 29 deletions
19
AGENTS.md
19
AGENTS.md
|
|
@ -158,6 +158,25 @@ v2/main/
|
|||
│ │ # and TUI schemaToForm — since each dispatches on
|
||||
│ │ # a single `type` string and would otherwise miss
|
||||
│ │ # a nullable field entirely — #1928/#2015;
|
||||
│ │ # rootUnion.ts: flattens the COMPOSITION keywords a
|
||||
│ │ # tool's inputSchema may carry at its ROOT — `allOf`
|
||||
│ │ # merged unconditionally (conjunctive, so there is
|
||||
│ │ # no choice to present), a root `oneOf`/`anyOf`
|
||||
│ │ # returned as the BRANCHES a picker chooses between.
|
||||
│ │ # Legal since 2026-07-28 and rendered as an EMPTY
|
||||
│ │ # FORM before — no picker, no fields, not even the
|
||||
│ │ # raw-JSON fallback a union-typed *property* gets,
|
||||
│ │ # so the tool could only be called with empty
|
||||
│ │ # arguments. Read by all three clients: web
|
||||
│ │ # SchemaForm (the Variant picker + the branch-change
|
||||
│ │ # value pruning), TUI schemaToForm (a section per
|
||||
│ │ # branch, its fields forced OPTIONAL since only one
|
||||
│ │ # alternative applies), and convertToolParameters
|
||||
│ │ # (which branch's schema types a CLI --tool-arg).
|
||||
│ │ # Declines a union whose members are not ALL
|
||||
│ │ # field-carrying objects rather than offering a
|
||||
│ │ # picker with options that render nothing, and does
|
||||
│ │ # not interpret `not` at all — #2123;
|
||||
│ │ # schemaLint.ts: tool-schema PORTABILITY lint —
|
||||
│ │ # constructs that are legal JSON Schema and are
|
||||
│ │ # refused or mishandled by real MCP clients (a bare
|
||||
|
|
|
|||
Loading…
Reference in a new issue