Skip to main content
Glama

GenAIScript

Official
by microsoft
MIT License
43
2,820
  • Linux
  • Apple
JSONSchema.tsx11.1 kB
/// <reference path="../../core/src/types/prompt_template.d.ts" /> /// <reference path="./vscode-elements.d.ts" /> import React, { Dispatch, SetStateAction, startTransition, useEffect, useState, } from "react" import { underscore } from "inflection" import "@vscode-elements/elements/dist/vscode-textarea" import "@vscode-elements/elements/dist/vscode-textfield" import "@vscode-elements/elements/dist/vscode-single-select" import "@vscode-elements/elements/dist/vscode-option" import "@vscode-elements/elements/dist/vscode-checkbox" import "@vscode-elements/elements/dist/vscode-checkbox-group" import "@vscode-elements/elements/dist/vscode-form-container" import "@vscode-elements/elements/dist/vscode-form-group" import "@vscode-elements/elements/dist/vscode-form-helper" import "@vscode-elements/elements/dist/vscode-label" import Markdown from "./Markdown" function JSONSchemaString(props: { field: JSONSchemaString value: string required?: boolean onChange: (value: string) => void }) { const { field } = props if (field.enum) return <JSONSchemaStringEnum {...props} /> if (field.uiSuggestions) return <JSONSchemaStringSuggestions {...props} /> if (field.uiType === "textarea") return <JSONSchemaStringTextArea {...props} /> return <JSONSchemaStringTextField {...props} /> } function JSONSchemaStringTextField(props: { field: JSONSchemaString value: string required?: boolean onChange: (value: string) => void }) { const { field, required, value, onChange } = props const { pattern } = field return ( <vscode-textfield pattern={pattern} value={value} required={required} spellCheck={false} placeholder={field.default} autoCapitalize="off" autocomplete="off" onInput={(e) => { const target = e.target as HTMLInputElement onChange(target.value) }} /> ) } function JSONSchemaStringTextArea(props: { field: JSONSchemaString value: string required?: boolean onChange: (value: string) => void }) { const { field, required, value, onChange } = props const rows = (s: string | undefined) => Math.max(3, s?.split("\n").length ?? 0) return ( <vscode-textarea className="vscode-form-wide" value={value} required={required} rows={rows(value)} spellCheck={true} placeholder={field.default} autoCapitalize="off" autocomplete="off" onInput={(e) => { const target = e.target as HTMLTextAreaElement target.rows = rows(target.value) onChange(target.value) }} /> ) } function JSONSchemaStringSuggestions(props: { field: JSONSchemaString value: string required?: boolean onChange: (value: string) => void }) { const { field, required, value, onChange } = props const { uiSuggestions: options } = field return ( <vscode-single-select value={value} required={required} creatable combobox onvsc-change={(e: Event) => { const target = e.target as HTMLSelectElement onChange(target.value) }} > <vscode-option key="empty" value=""></vscode-option> {options.map((option) => ( <vscode-option key={option} value={option}> {option} </vscode-option> ))} </vscode-single-select> ) } function JSONSchemaStringEnum(props: { field: JSONSchemaString value: string required?: boolean onChange: (value: string) => void }) { const { field, required, value, onChange } = props const { enum: options } = field return ( <vscode-single-select value={value} required={required} combobox onvsc-change={(e: Event) => { const target = e.target as HTMLSelectElement onChange(target.value) }} > <vscode-option key="empty" value=""></vscode-option> {options.map((option) => ( <vscode-option key={option} value={option}> {option} </vscode-option> ))} </vscode-single-select> ) } function JSONSchemaNumber(props: { schema: JSONSchemaNumber value: number required: boolean onChange: (value: number) => void }) { const { required, schema, value, onChange } = props const { type, minimum, maximum } = schema const [valueText, setValueText] = useState( isNaN(value) ? "" : String(value) ) useEffect(() => { const v = type === "number" ? parseFloat(valueText) : parseInt(valueText) if (!isNaN(v) && v !== value) onChange(v) }, [valueText]) return ( <vscode-textfield value={valueText} required={required} placeholder={isNaN(schema.default) ? "" : String(schema.default)} min={minimum} max={maximum} autoCapitalize="off" autocomplete="off" inputMode={type === "number" ? "decimal" : "numeric"} onInput={(e) => { const target = e.target as HTMLInputElement startTransition(() => setValueText(target.value)) }} /> ) } function JSONSchemaSimpleTypeFormField(props: { field: JSONSchemaSimpleType value: string | boolean | number | object required?: boolean onChange: (value: string | boolean | number | object) => void }) { const { field, required, value, onChange } = props switch (field.type) { case "number": case "integer": return ( <JSONSchemaNumber schema={field} value={Number(value)} onChange={onChange} required={required} /> ) case "string": { return ( <JSONSchemaString field={field} value={value as string} required={required} onChange={onChange} /> ) } case "boolean": return ( <vscode-checkbox checked={value as boolean} required={required} onChange={(e) => { const target = e.target as HTMLInputElement onChange(target.checked) }} /> ) default: return ( <vscode-textfield spellCheck={false} value={value as string} required={required} onInput={(e) => { const target = e.target as HTMLInputElement onChange(target.value) }} /> ) } } function fieldDisplayName( fieldPrefix: string, fieldName: string, field: JSONSchemaSimpleType ) { return underscore( (fieldPrefix ? `${fieldPrefix} / ` : fieldPrefix) + (field.title || fieldName) ).replaceAll(/[_\.]/g, " ") } export function JSONBooleanOptionsGroup(props: { properties: Record<string, JSONSchemaBoolean> value: any onChange: Dispatch<SetStateAction<any>> fieldPrefix: string }) { const { properties, value, onChange, fieldPrefix } = props const handleFieldChange = (fieldName: string, value: any) => { onChange((prev: any) => ({ ...prev, [fieldName]: value, })) } if (!properties) return null return ( <vscode-checkbox-group> {Object.entries(properties).map(([fieldName, field]) => ( <vscode-checkbox key={fieldName} label={fieldDisplayName(fieldPrefix, fieldName, field)} title={field.description} checked={value[fieldPrefix + fieldName]} onChange={(e) => handleFieldChange( fieldPrefix + fieldName, (e.target as HTMLInputElement).checked ) } /> ))} </vscode-checkbox-group> ) } export function JSONSchemaObjectForm(props: { schema: JSONSchemaObject value: any onChange: Dispatch<SetStateAction<any>> fieldPrefix: string }) { const { schema, value, onChange, fieldPrefix } = props const properties: Record<string, JSONSchemaSimpleType> = schema.properties ?? ({} as any) const groupedProperties = Object.groupBy( Object.entries(properties), ([, field]) => field.uiGroup || "" ) return ( <> {Object.entries(groupedProperties).map(([group, fields]) => ( <JSONSchemaObjectPropertiesForm key={group || ""} schema={schema} group={group} properties={fields} value={value} onChange={onChange} fieldPrefix={fieldPrefix} /> ))} </> ) } function JSONSchemaObjectPropertiesForm(props: { schema: JSONSchemaObject group: string properties: [string, JSONSchemaSimpleType][] value: any onChange: Dispatch<SetStateAction<any>> fieldPrefix: string }) { const { group, schema, properties, value, onChange, fieldPrefix } = props const handleFieldChange = (fieldName: string, value: any) => { onChange((prev: any) => ({ ...prev, [fieldName]: value, })) } const fieldElements = properties.map(([fieldName, field]) => ( <vscode-form-group key={fieldPrefix + fieldName}> <vscode-label> {fieldDisplayName(fieldPrefix, fieldName, field)} </vscode-label> <JSONSchemaSimpleTypeFormField field={field} value={value[fieldPrefix + fieldName]} required={schema.required?.includes(fieldName)} onChange={(value) => handleFieldChange(fieldPrefix + fieldName, value) } /> {field?.description && ( <vscode-form-helper> <Markdown>{field.description}</Markdown> </vscode-form-helper> )} </vscode-form-group> )) if (!group) return fieldElements return ( <vscode-collapsible title={group} open={false}> {fieldElements} </vscode-collapsible> ) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/microsoft/genaiscript'

If you have feedback or need assistance with the MCP directory API, please join our Discord server