export default function SchemaPreview( { state, definitions } ) { function generateSchema() { const properties = {}; const seenKeys = {}; const resultKeys = []; const TYPE_MAP = { NUMERIC: 'number', DECIMAL: 'number', UNSIGNED: 'number' }; const FORMAT_MAP = { NUMERIC: 'integer (e.g. 29)', UNSIGNED: 'positive integer (e.g. 100)', DECIMAL: 'decimal (e.g. 29.99)', DATE: 'date (YYYY-MM-DD)', DATETIME: 'date-time (YYYY-MM-DDTHH:MM:SS)', TIME: 'time (HH:MM:SS)', }; const ARRAY_OPS = [ 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ]; const EXISTS_OPS = [ 'EXISTS', 'NOT EXISTS' ]; ( state.blocks || [] ).forEach( ( block, index ) => { const def = definitions[ block.block_type ]; if ( ! def ) { return; } // Compute result_key — mirrors tool executor and handle_tools_list() logic. // Only Posts blocks use post_type as the key; other block types ignore the // field even if a legacy phantom value is present in saved config. let resultKey = ( 'posts' === block.block_type && block.config.post_type ) ? block.config.post_type : block.block_type; if ( seenKeys[ resultKey ] !== undefined ) { resultKey = `${ resultKey }_${ index }`; } seenKeys[ resultKey ] = true; resultKeys.push( resultKey ); const prefix = `${ resultKey }_`; // Standard filters. const availableFilters = def.filters || {}; Object.entries( block.config.filters || {} ).forEach( ( [ key, filterConfig ] ) => { if ( ! filterConfig.enabled || ! availableFilters[ key ] ) { return; } const prop = { ...availableFilters[ key ] }; if ( filterConfig.description ) { prop.description = filterConfig.description; } properties[ prefix + key ] = prop; } ); // Taxonomy filters. Object.entries( block.config.taxonomies || {} ).forEach( ( [ taxSlug, taxConfig ] ) => { if ( ! taxConfig.as_filter ) { return; } const prop = { type: 'string', description: `Filter by ${ taxSlug }`, }; if ( taxConfig.terms && taxConfig.terms.length > 0 ) { prop.enum = taxConfig.terms; } properties[ prefix + taxSlug ] = prop; } ); // Meta key filters — mirrors server-side get_input_schema_properties(). Object.entries( block.config.meta_keys || {} ).forEach( ( [ metaKey, metaConfig ] ) => { if ( ! metaConfig.as_filter || metaKey.includes( '%' ) ) { return; } const metaType = metaConfig.type || 'CHAR'; const compare = metaConfig.compare || [ '=' ]; const schemaType = TYPE_MAP[ metaType ] || 'string'; const baseSchema = { type: schemaType }; if ( FORMAT_MAP[ metaType ] ) { baseSchema.format = FORMAT_MAP[ metaType ]; } const hasArrayOps = compare.some( ( c ) => ARRAY_OPS.includes( c ) ); const hasScalarOps = compare.some( ( c ) => ! ARRAY_OPS.includes( c ) && ! EXISTS_OPS.includes( c ) ); const hasExistsOnly = ! hasArrayOps && ! hasScalarOps; let valueSchema; if ( hasArrayOps && hasScalarOps ) { valueSchema = { oneOf: [ { ...baseSchema }, { type: 'array', items: { ...baseSchema } } ] }; } else if ( hasArrayOps ) { valueSchema = { type: 'array', items: { ...baseSchema } }; } else { valueSchema = { ...baseSchema }; } const itemRequired = hasExistsOnly ? [ 'compare' ] : [ 'value', 'compare' ]; const itemProperties = { compare: { type: 'string', enum: compare }, }; if ( ! hasExistsOnly ) { itemProperties.value = valueSchema; } properties[ prefix + metaKey ] = { type: 'array', items: { type: 'object', properties: itemProperties, required: itemRequired, }, description: `Filter by ${ metaKey }`, }; } ); } ); // For multi-block tools, add _blocks — mirrors handle_tools_list(). if ( resultKeys.length > 1 ) { properties._blocks = { type: 'array', description: 'Optional. List which blocks to execute by result key. Omit to run all blocks.', items: { type: 'string', enum: resultKeys, }, }; } return { name: state.tool_name || 'untitled_tool', description: state.description || '', inputSchema: { type: 'object', properties: Object.keys( properties ).length > 0 ? properties : {}, }, }; } const schema = generateSchema(); return (

Schema Preview

What the AI will see

				{ JSON.stringify( schema, null, 2 ) }
			
); }