Phase 2: Refactor Sampling/Elicitation cluster to MCP SDK types

Replace ad hoc local types with SDK schema types across the Sampling
and Elicitation group components.

- SamplingRequestPanel: accept `request: CreateMessageRequestParams` +
  `draftResult: CreateMessageResult` instead of 16 flat props; derive
  messages, model preferences, and parameters from the request object;
  drop `tools`/`toolChoice` (not in MCP 2025-11-25 CreateMessageRequest)
- InlineSamplingRequest: accept `request: CreateMessageRequestParams`;
  derive messagePreview and modelHints from the request
- ElicitationFormPanel: accept `request: ElicitRequest['params']` +
  `serverName`; pass requestedSchema directly to SchemaForm
- ElicitationUrlPanel: rename `elicitationId` to `requestId`
- InlineElicitationRequest: accept `request: ElicitRequest['params']`;
  discriminate form vs URL mode on request shape instead of `mode` prop
- PendingClientRequests: unchanged (children-based wrapper)
- Delete local `SamplingTool` type
- Update all stories with real SDK type fixtures

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-20 19:57:58 -04:00
commit c1a63cb37d

View file

@ -8,16 +8,14 @@ import {
Stack,
Text,
} from "@mantine/core";
import type { JsonSchema } from "../SchemaForm/SchemaForm";
import type { ElicitRequest } from "@modelcontextprotocol/sdk/types.js";
import { SchemaForm } from "../SchemaForm/SchemaForm";
import type { JsonSchema } from "../SchemaForm/SchemaForm";
export interface InlineElicitationRequestProps {
mode: "form" | "url";
message: string;
request: ElicitRequest["params"];
queuePosition: string;
schema?: JsonSchema;
values?: Record<string, unknown>;
url?: string;
isWaiting?: boolean;
onChange: (values: Record<string, unknown>) => void;
onSubmit: () => void;
@ -49,45 +47,52 @@ const CompactButton = Button.withProps({
variant: "light",
});
function getBadgeLabel(mode: "form" | "url"): string {
return mode === "form"
function isFormMode(
request: ElicitRequest["params"],
): request is ElicitRequest["params"] & {
requestedSchema: Record<string, unknown>;
} {
return "requestedSchema" in request;
}
function getBadgeLabel(request: ElicitRequest["params"]): string {
return isFormMode(request)
? "elicitation/create (form)"
: "elicitation/create (url)";
}
export function InlineElicitationRequest({
mode,
message,
request,
queuePosition,
schema,
values,
url,
isWaiting,
onChange,
onSubmit,
onCancel,
}: InlineElicitationRequestProps) {
const formMode = isFormMode(request);
return (
<RequestContainer>
<Stack gap="sm">
<Group justify="space-between">
<Badge color="violet">{getBadgeLabel(mode)}</Badge>
<Badge color="violet">{getBadgeLabel(request)}</Badge>
<QueueLabel>{queuePosition}</QueueLabel>
</Group>
<ItalicMessage>{message}</ItalicMessage>
<ItalicMessage>{request.message}</ItalicMessage>
{mode === "form" && schema && (
{formMode && (
<SchemaForm
schema={schema}
schema={request.requestedSchema as JsonSchema}
values={values ?? {}}
onChange={onChange}
/>
)}
{mode === "url" && url && (
{!formMode && "url" in request && (
<>
<Code block>{url}</Code>
<Code block>{(request as { url: string }).url}</Code>
{isWaiting && (
<Group>
<Loader size="xs" />
@ -99,7 +104,7 @@ export function InlineElicitationRequest({
<ActionsRow>
<CompactButton onClick={onCancel}>Cancel</CompactButton>
{mode === "form" && (
{formMode && (
<Button size="xs" onClick={onSubmit}>
Submit
</Button>