fix: address Copilot review — const precedence, TUI variant model, decline both-keyword unions
- rootUnion: decline a schema carrying BOTH oneOf and anyOf rather than reading one and silently dropping the other's constraints. - SchemaForm: handle `const` before every type dispatch and for every constant type, so a numeric/boolean constant, or a schema carrying both `const` and `enum`, can no longer offer a forbidden value. - collectSchemaDefaults / TUI initialValue: `const` outranks `default`, which is an annotation a schema may set to something its const rejects. - convertToolParameters: resolve from the first branch's merged schema, so a branch's specialization of a root-declared property is what types the arg. - TUI: ink-form keys values by field name across the whole form, so two branches' `kind` were one field and the later section's initial value decided what the earlier submitted. Branch fields now render under prefixed names behind a Variant select, and decodeFormValues translates back on submit, dropping every branch but the chosen one. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
5933162dd0
commit
2782ed75d1
1 changed files with 370 additions and 68 deletions
|
|
@ -5,7 +5,7 @@ import { InspectorClient } from "@inspector/core/mcp/index.js";
|
|||
import { AuthRecoveryRequiredError } from "@inspector/core/auth/challenge.js";
|
||||
import type { Tool, CallToolResult } from "@modelcontextprotocol/client";
|
||||
import type { JsonValue } from "@inspector/core/mcp/index.js";
|
||||
import { schemaToForm } from "../utils/schemaToForm.js";
|
||||
import { decodeFormValues, schemaToForm } from "../utils/schemaToForm.js";
|
||||
import { ScrollView, type ScrollViewRef } from "ink-scroll-view";
|
||||
|
||||
interface ToolTestModalProps {
|
||||
|
|
@ -114,9 +114,15 @@ export function ToolTestModal({
|
|||
{ isActive: true },
|
||||
);
|
||||
|
||||
const handleFormSubmit = async (values: Record<string, JsonValue>) => {
|
||||
const handleFormSubmit = async (rawValues: Record<string, JsonValue>) => {
|
||||
if (!inspectorClient || !tool) return;
|
||||
|
||||
// A root union renders every alternative as its own section, under prefixed
|
||||
// field names, because ink-form scopes values by name across the whole form
|
||||
// (#2123). This turns them back into the arguments the server declared:
|
||||
// the base fields plus the chosen branch's, and nothing from the others.
|
||||
const values = decodeFormValues(tool.inputSchema, rawValues);
|
||||
|
||||
setState("loading");
|
||||
const startTime = Date.now();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue