← All changes
|
modules/mcp/abilities/utils/widget-context-helper.php
+38
-1
4.3.0-beta2
→
4.3.1
View file →
| @@ -42,8 +42,10 @@ | ||
| 42 | 42 | const V3_FALLBACK_MESSAGE = '`properties` lists the only keys accepted in `element_config` / `manage-elements.settings` for this widget. Put all visual styling in the `style` (CSS) input.'; |
| 43 | 43 | |
| 44 | 44 | const V3_FALLBACK_FIELDS_NOTE = 'All properties are optional. Object-typed properties describe common shapes but do not include exhaustive inner validation.'; |
| 45 | 45 | |
| 46 | + const ALLOWED_HTML_TAGS_NOTE = 'May contain inline HTML written directly in the string (e.g. "Hello <strong>world</strong>"), limited to these tags: %s. Any other tag is stripped on save.'; | |
| 47 | + | |
| 46 | 48 | /** |
| 47 | 49 | * @return array<string, array> widget_type => config, filtered to widgets eligible for LLM use. |
| 48 | 50 | */ |
| 49 | 51 | public static function get_llm_eligible_widgets(): array { |
| @@ -192,9 +194,9 @@ | ||
| 192 | 194 | $schema = self::to_plain_llm_schema_from_json( $prop_type->to_json_schema() ); |
| 193 | 195 | $allowed_html_tags = Escaped_Html_Prop_Type::get_allowed_html_tags_for_prop( $widget_type, $key ); |
| 194 | 196 | |
| 195 | 197 | if ( null !== $allowed_html_tags ) { |
| 196 | - $schema['allowed_html_tags'] = $allowed_html_tags; | |
| 198 | + $schema = self::describe_allowed_html_tags( $schema, $allowed_html_tags ); | |
| 197 | 199 | } |
| 198 | 200 | |
| 199 | 201 | $properties[ $key ] = $schema; |
| 200 | 202 | } |
| @@ -199,8 +201,43 @@ | ||
| 199 | 201 | $properties[ $key ] = $schema; |
| 200 | 202 | } |
| 201 | 203 | |
| 202 | 204 | return $properties; |
| 205 | + } | |
| 206 | + | |
| 207 | + /** | |
| 208 | + * Keeps the machine-readable tag list while spelling out in the description that the string | |
| 209 | + * itself may carry that markup — a bare `allowed_html_tags` key is non-standard JSON Schema | |
| 210 | + * and reads as ambiguous next to `type: string`. | |
| 211 | + */ | |
| 212 | + private static function describe_allowed_html_tags( array $schema, array $allowed_html_tags ): array { | |
| 213 | + $schema['allowed_html_tags'] = $allowed_html_tags; | |
| 214 | + | |
| 215 | + $tag_list = implode( ', ', array_map( fn( $tag ) => "<{$tag}>", $allowed_html_tags ) ); | |
| 216 | + $note = sprintf( self::ALLOWED_HTML_TAGS_NOTE, $tag_list ); | |
| 217 | + | |
| 218 | + if ( ! isset( $schema['anyOf'] ) || ! is_array( $schema['anyOf'] ) ) { | |
| 219 | + return self::append_description( $schema, $note ); | |
| 220 | + } | |
| 221 | + | |
| 222 | + // The markup rule belongs on the static string variant only — a dynamic-tag branch | |
| 223 | + // resolves its own value and never carries inline HTML from the caller. | |
| 224 | + $schema['anyOf'] = array_map( | |
| 225 | + fn( $branch ) => is_array( $branch ) && 'string' === ( $branch['type'] ?? null ) | |
| 226 | + ? self::append_description( $branch, $note ) | |
| 227 | + : $branch, | |
| 228 | + $schema['anyOf'] | |
| 229 | + ); | |
| 230 | + | |
| 231 | + return $schema; | |
| 232 | + } | |
| 233 | + | |
| 234 | + private static function append_description( array $schema, string $note ): array { | |
| 235 | + $schema['description'] = isset( $schema['description'] ) | |
| 236 | + ? $schema['description'] . ' ' . $note | |
| 237 | + : $note; | |
| 238 | + | |
| 239 | + return $schema; | |
| 203 | 240 | } |
| 204 | 241 | |
| 205 | 242 | public static function to_plain_llm_schema( Prop_Type $prop_type ): array { |
| 206 | 243 | $schema = self::to_plain_llm_schema_from_json( $prop_type->to_json_schema() ); |