wp-typia 0.22.1 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import {
4
4
  REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY,
5
5
  assertExternalLayerCompositionOptions,
6
6
  copyInterpolatedDirectory,
7
+ createScaffoldCompatibilityConfig,
7
8
  getDefaultAnswers,
8
9
  listInterpolatedDirectoryOutputs,
9
10
  normalizeOptionalCliString,
@@ -20,7 +21,7 @@ import {
20
21
  scaffoldProject,
21
22
  syncPersistenceRestArtifacts,
22
23
  updatePluginHeaderCompatibility
23
- } from "./cli-886tjd8m.js";
24
+ } from "./cli-kww2sraq.js";
24
25
  import {
25
26
  DEFAULT_WORDPRESS_ABILITIES_VERSION,
26
27
  DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION,
@@ -33,7 +34,7 @@ import {
33
34
  } from "./cli-1sm60g1z.js";
34
35
  import {
35
36
  snapshotProjectVersion
36
- } from "./cli-yzmkz95r.js";
37
+ } from "./cli-6hcbjvym.js";
37
38
  import {
38
39
  ensureMigrationDirectories,
39
40
  parseMigrationConfig,
@@ -94,7 +95,7 @@ import {
94
95
  toPascalCase,
95
96
  toSnakeCase,
96
97
  toTitleCase
97
- } from "./cli-5md428hf.js";
98
+ } from "./cli-smzkbfna.js";
98
99
  import {
99
100
  createManagedTempRoot
100
101
  } from "./cli-t73q5aqz.js";
@@ -5435,6 +5436,45 @@ export interface ${pascalCase}AiFeatureResponse {
5435
5436
  result: ${pascalCase}AiFeatureResult;
5436
5437
  telemetry: ${pascalCase}AiFeatureTelemetry;
5437
5438
  }
5439
+
5440
+ export type ${pascalCase}AiFeatureSupportProbeMode = 'request-time';
5441
+
5442
+ export type ${pascalCase}AiFeatureUnavailableErrorCode =
5443
+ 'ai_client_unavailable';
5444
+
5445
+ export type ${pascalCase}AiFeatureUnavailableReasonCode =
5446
+ | 'missing-wordpress-ai-client'
5447
+ | 'request-time-support-probe';
5448
+
5449
+ export interface ${pascalCase}AiFeatureSupportReason {
5450
+ code: ${pascalCase}AiFeatureUnavailableReasonCode;
5451
+ label: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
5452
+ message: string & tags.MinLength< 1 > & tags.MaxLength< 4000 >;
5453
+ }
5454
+
5455
+ export interface ${pascalCase}AiFeatureSupportMetadata {
5456
+ featureLabel: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
5457
+ featureSlug: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
5458
+ compatibility: {
5459
+ hardMinimums: {
5460
+ php?: string;
5461
+ wordpress?: string;
5462
+ };
5463
+ mode: 'baseline' | 'optional' | 'required';
5464
+ optionalFeatureIds: string[];
5465
+ optionalFeatures: string[];
5466
+ requiredFeatureIds: string[];
5467
+ requiredFeatures: string[];
5468
+ runtimeGates: string[];
5469
+ };
5470
+ supportProbe: {
5471
+ endpointMethod: 'POST';
5472
+ endpointPath: string & tags.MinLength< 1 > & tags.MaxLength< 200 >;
5473
+ mode: ${pascalCase}AiFeatureSupportProbeMode;
5474
+ unavailableErrorCode: ${pascalCase}AiFeatureUnavailableErrorCode;
5475
+ };
5476
+ unavailableReasons: ${pascalCase}AiFeatureSupportReason[];
5477
+ }
5438
5478
  `;
5439
5479
  }
5440
5480
  function buildAiFeatureValidatorsSource(aiFeatureSlug) {
@@ -5470,6 +5510,8 @@ export const apiValidators = {
5470
5510
  }
5471
5511
  function buildAiFeatureApiSource(aiFeatureSlug) {
5472
5512
  const pascalCase = toPascalCase(aiFeatureSlug);
5513
+ const compatibility = createScaffoldCompatibilityConfig(resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY));
5514
+ const title = toTitleCase(aiFeatureSlug);
5473
5515
  return `import {
5474
5516
  callEndpoint,
5475
5517
  resolveRestRouteUrl,
@@ -5477,6 +5519,7 @@ function buildAiFeatureApiSource(aiFeatureSlug) {
5477
5519
 
5478
5520
  import type {
5479
5521
  ${pascalCase}AiFeatureRequest,
5522
+ ${pascalCase}AiFeatureSupportMetadata,
5480
5523
  } from './api-types';
5481
5524
  import {
5482
5525
  run${pascalCase}AiFeatureEndpoint,
@@ -5503,6 +5546,14 @@ function resolveRestNonce( fallback?: string ): string | undefined {
5503
5546
  : undefined;
5504
5547
  }
5505
5548
 
5549
+ function isPlainObject( value: unknown ): value is Record< string, unknown > {
5550
+ return (
5551
+ !! value &&
5552
+ typeof value === 'object' &&
5553
+ ! Array.isArray( value )
5554
+ );
5555
+ }
5556
+
5506
5557
  export const aiFeatureRunEndpoint = {
5507
5558
  ...run${pascalCase}AiFeatureEndpoint,
5508
5559
  buildRequestOptions: () => {
@@ -5518,6 +5569,63 @@ export const aiFeatureRunEndpoint = {
5518
5569
  },
5519
5570
  };
5520
5571
 
5572
+ export const aiFeatureSupportMetadata = {
5573
+ compatibility: ${JSON.stringify(compatibility, null, "\t")},
5574
+ featureLabel: ${quoteTsString(title)},
5575
+ featureSlug: ${quoteTsString(aiFeatureSlug)},
5576
+ supportProbe: {
5577
+ endpointMethod: 'POST',
5578
+ endpointPath: aiFeatureRunEndpoint.path,
5579
+ mode: 'request-time',
5580
+ unavailableErrorCode: 'ai_client_unavailable',
5581
+ },
5582
+ unavailableReasons: [
5583
+ {
5584
+ code: 'missing-wordpress-ai-client',
5585
+ label: 'WordPress AI Client unavailable',
5586
+ message:
5587
+ 'This AI feature stays disabled until the WordPress AI Client is available on the site.',
5588
+ },
5589
+ {
5590
+ code: 'request-time-support-probe',
5591
+ label: 'Support is checked at request time',
5592
+ message:
5593
+ 'Support is verified when the feature runs, so editor and admin UIs should degrade gracefully when the site rejects the request.',
5594
+ },
5595
+ ],
5596
+ } satisfies ${pascalCase}AiFeatureSupportMetadata;
5597
+
5598
+ export function getAiFeatureSupportHintLines() {
5599
+ return aiFeatureSupportMetadata.unavailableReasons.map(
5600
+ ( reason ) => reason.message
5601
+ );
5602
+ }
5603
+
5604
+ export function isAiFeatureSupportUnavailableError( error: unknown ) {
5605
+ if ( ! isPlainObject( error ) ) {
5606
+ return false;
5607
+ }
5608
+
5609
+ const data = isPlainObject( error.data ) ? error.data : undefined;
5610
+ return (
5611
+ error.code === aiFeatureSupportMetadata.supportProbe.unavailableErrorCode ||
5612
+ data?.status === 501
5613
+ );
5614
+ }
5615
+
5616
+ export function resolveAiFeatureUnavailableMessage( error: unknown ) {
5617
+ if (
5618
+ isPlainObject( error ) &&
5619
+ typeof error.message === 'string' &&
5620
+ error.message.length > 0
5621
+ ) {
5622
+ return error.message;
5623
+ }
5624
+
5625
+ return aiFeatureSupportMetadata.unavailableReasons[ 0 ]?.message ??
5626
+ 'This AI feature is currently unavailable.';
5627
+ }
5628
+
5521
5629
  export function runAiFeature( request: ${pascalCase}AiFeatureRequest ) {
5522
5630
  return callEndpoint( aiFeatureRunEndpoint, request );
5523
5631
  }
@@ -5536,6 +5644,10 @@ import type {
5536
5644
  } from './api-types';
5537
5645
  import {
5538
5646
  aiFeatureRunEndpoint,
5647
+ aiFeatureSupportMetadata,
5648
+ getAiFeatureSupportHintLines,
5649
+ isAiFeatureSupportUnavailableError,
5650
+ resolveAiFeatureUnavailableMessage,
5539
5651
  } from './api';
5540
5652
 
5541
5653
  export type UseRun${pascalCase}AiFeatureMutationOptions =
@@ -5550,6 +5662,13 @@ export function useRun${pascalCase}AiFeatureMutation(
5550
5662
  ) {
5551
5663
  return useEndpointMutation( aiFeatureRunEndpoint, options );
5552
5664
  }
5665
+
5666
+ export {
5667
+ aiFeatureSupportMetadata,
5668
+ getAiFeatureSupportHintLines,
5669
+ isAiFeatureSupportUnavailableError,
5670
+ resolveAiFeatureUnavailableMessage,
5671
+ };
5553
5672
  `;
5554
5673
  }
5555
5674
  function buildAiFeatureSyncScriptSource() {
@@ -5962,18 +6081,40 @@ function buildAiFeaturePhpSource(aiFeatureSlug, namespace, phpPrefix, textDomain
5962
6081
  const normalizeSchemaFunctionName = `${phpPrefix}_${aiFeaturePhpId}_sanitize_ai_feature_schema`;
5963
6082
  const validatePayloadFunctionName = `${phpPrefix}_${aiFeaturePhpId}_validate_ai_feature_payload`;
5964
6083
  const canManageFunctionName = `${phpPrefix}_${aiFeaturePhpId}_can_manage_ai_feature`;
6084
+ const normalizePromptPayloadFunctionName = `${phpPrefix}_${aiFeaturePhpId}_normalize_ai_feature_prompt_payload`;
5965
6085
  const buildPromptFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_prompt`;
6086
+ const resolvePromptOptionsFunctionName = `${phpPrefix}_${aiFeaturePhpId}_resolve_ai_feature_prompt_options`;
5966
6087
  const normalizeProviderTypeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_normalize_provider_type`;
5967
6088
  const buildTelemetryFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_telemetry`;
6089
+ const resolveUnavailableMessageFunctionName = `${phpPrefix}_${aiFeaturePhpId}_resolve_ai_feature_unavailable_message`;
5968
6090
  const isSupportedFunctionName = `${phpPrefix}_${aiFeaturePhpId}_is_ai_feature_supported`;
5969
6091
  const adminNoticeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_admin_notice`;
5970
6092
  const handlerFunctionName = `${phpPrefix}_${aiFeaturePhpId}_handle_run_ai_feature`;
5971
6093
  const registerRoutesFunctionName = `${phpPrefix}_${aiFeaturePhpId}_register_ai_feature_routes`;
6094
+ const permissionFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_permission`;
6095
+ const promptPayloadFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt_payload`;
6096
+ const promptFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt`;
6097
+ const promptOptionsFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt_options`;
6098
+ const adminNoticeMessageFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_admin_notice_message`;
6099
+ const unavailableMessageFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_unavailable_message`;
6100
+ const telemetryFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_telemetry`;
5972
6101
  return `<?php
5973
6102
  if ( ! defined( 'ABSPATH' ) ) {
5974
6103
  return;
5975
6104
  }
5976
6105
 
6106
+ /*
6107
+ * Customization hooks for the ${aiFeatureTitle} AI feature:
6108
+ *
6109
+ * - ${quotePhpString(permissionFilterHook)} filters the default current_user_can( 'edit_posts' ) capability check.
6110
+ * - ${quotePhpString(promptPayloadFilterHook)} filters the validated request payload array before prompt serialization.
6111
+ * - ${quotePhpString(promptFilterHook)} filters the final prompt string after payload normalization.
6112
+ * - ${quotePhpString(promptOptionsFilterHook)} filters prompt options with \`temperature\` and \`modelPreference\` keys.
6113
+ * - ${quotePhpString(adminNoticeMessageFilterHook)} filters the wp-admin notice shown when AI support is unavailable.
6114
+ * - ${quotePhpString(unavailableMessageFilterHook)} filters REST-facing unavailable messages by reason code.
6115
+ * - ${quotePhpString(telemetryFilterHook)} filters the response telemetry array before schema validation. Return a schema-compatible array.
6116
+ */
6117
+
5977
6118
  if ( ! function_exists( '${loadSchemaFunctionName}' ) ) {
5978
6119
  function ${loadSchemaFunctionName}( $schema_name ) {
5979
6120
  $project_root = dirname( __DIR__, 2 );
@@ -6040,17 +6181,111 @@ if ( ! function_exists( '${validatePayloadFunctionName}' ) ) {
6040
6181
  }
6041
6182
 
6042
6183
  if ( ! function_exists( '${canManageFunctionName}' ) ) {
6043
- function ${canManageFunctionName}() {
6044
- return current_user_can( 'edit_posts' );
6184
+ function ${canManageFunctionName}( WP_REST_Request $request = null ) {
6185
+ $permission = apply_filters(
6186
+ ${quotePhpString(permissionFilterHook)},
6187
+ current_user_can( 'edit_posts' ),
6188
+ $request
6189
+ );
6190
+ if ( is_wp_error( $permission ) ) {
6191
+ return $permission;
6192
+ }
6193
+ return (bool) $permission;
6194
+ }
6195
+ }
6196
+
6197
+ if ( ! function_exists( '${normalizePromptPayloadFunctionName}' ) ) {
6198
+ function ${normalizePromptPayloadFunctionName}( array $payload ) {
6199
+ $normalized_payload = apply_filters(
6200
+ ${quotePhpString(promptPayloadFilterHook)},
6201
+ $payload
6202
+ );
6203
+ return is_array( $normalized_payload ) ? $normalized_payload : $payload;
6045
6204
  }
6046
6205
  }
6047
6206
 
6048
6207
  if ( ! function_exists( '${buildPromptFunctionName}' ) ) {
6049
6208
  function ${buildPromptFunctionName}( array $payload ) {
6050
- return sprintf(
6209
+ $normalized_payload = ${normalizePromptPayloadFunctionName}( $payload );
6210
+ $prompt = sprintf(
6051
6211
  'You are helping with the %1$s AI workflow. Read the JSON request payload and return JSON that matches the provided schema. Request payload: %2$s',
6052
6212
  ${quotePhpString(aiFeatureTitle)},
6053
- wp_json_encode( $payload )
6213
+ wp_json_encode( $normalized_payload )
6214
+ );
6215
+ $filtered_prompt = apply_filters(
6216
+ ${quotePhpString(promptFilterHook)},
6217
+ $prompt,
6218
+ $normalized_payload,
6219
+ $payload
6220
+ );
6221
+ return is_string( $filtered_prompt ) && '' !== $filtered_prompt ? $filtered_prompt : $prompt;
6222
+ }
6223
+ }
6224
+
6225
+ if ( ! function_exists( '${resolvePromptOptionsFunctionName}' ) ) {
6226
+ function ${resolvePromptOptionsFunctionName}( array $payload = array() ) {
6227
+ $options = apply_filters(
6228
+ ${quotePhpString(promptOptionsFilterHook)},
6229
+ array(
6230
+ 'modelPreference' => array(),
6231
+ 'temperature' => 0.2,
6232
+ ),
6233
+ $payload
6234
+ );
6235
+ if ( ! is_array( $options ) ) {
6236
+ $options = array();
6237
+ }
6238
+
6239
+ $temperature = 0.2;
6240
+ if ( array_key_exists( 'temperature', $options ) ) {
6241
+ if ( null === $options['temperature'] ) {
6242
+ $temperature = null;
6243
+ } elseif ( is_numeric( $options['temperature'] ) ) {
6244
+ $temperature = (float) $options['temperature'];
6245
+ }
6246
+ }
6247
+
6248
+ $model_preferences = array();
6249
+ if ( isset( $options['modelPreference'] ) ) {
6250
+ $raw_model_preferences = $options['modelPreference'];
6251
+ if ( is_string( $raw_model_preferences ) && '' !== $raw_model_preferences ) {
6252
+ $model_preferences = array( $raw_model_preferences );
6253
+ } elseif ( is_array( $raw_model_preferences ) ) {
6254
+ $model_preferences = array_values(
6255
+ array_filter(
6256
+ array_map(
6257
+ static function ( $candidate ) {
6258
+ if ( is_string( $candidate ) && '' !== $candidate ) {
6259
+ return $candidate;
6260
+ }
6261
+ if ( ! is_array( $candidate ) ) {
6262
+ return null;
6263
+ }
6264
+
6265
+ $normalized = array_values(
6266
+ array_filter(
6267
+ $candidate,
6268
+ static function ( $value ) {
6269
+ return is_string( $value ) && '' !== $value;
6270
+ }
6271
+ )
6272
+ );
6273
+
6274
+ return count( $normalized ) > 0 ? $normalized : null;
6275
+ },
6276
+ $raw_model_preferences
6277
+ ),
6278
+ static function ( $candidate ) {
6279
+ return null !== $candidate;
6280
+ }
6281
+ )
6282
+ );
6283
+ }
6284
+ }
6285
+
6286
+ return array(
6287
+ 'modelPreference' => $model_preferences,
6288
+ 'temperature' => $temperature,
6054
6289
  );
6055
6290
  }
6056
6291
  }
@@ -6066,7 +6301,7 @@ if ( ! function_exists( '${normalizeProviderTypeFunctionName}' ) ) {
6066
6301
  }
6067
6302
 
6068
6303
  if ( ! function_exists( '${buildTelemetryFunctionName}' ) ) {
6069
- function ${buildTelemetryFunctionName}( $result ) {
6304
+ function ${buildTelemetryFunctionName}( $result, array $payload = array(), array $normalized_result = array() ) {
6070
6305
  if (
6071
6306
  ! is_object( $result ) ||
6072
6307
  ! method_exists( $result, 'getId' ) ||
@@ -6126,47 +6361,95 @@ if ( ! function_exists( '${buildTelemetryFunctionName}' ) ) {
6126
6361
  }
6127
6362
  }
6128
6363
 
6129
- return $telemetry;
6364
+ $filtered_telemetry = apply_filters(
6365
+ ${quotePhpString(telemetryFilterHook)},
6366
+ $telemetry,
6367
+ $result,
6368
+ $payload,
6369
+ $normalized_result
6370
+ );
6371
+ return is_array( $filtered_telemetry ) ? $filtered_telemetry : $telemetry;
6372
+ }
6373
+ }
6374
+
6375
+ if ( ! function_exists( '${resolveUnavailableMessageFunctionName}' ) ) {
6376
+ function ${resolveUnavailableMessageFunctionName}( $message, $reason, array $context = array() ) {
6377
+ $filtered_message = apply_filters(
6378
+ ${quotePhpString(unavailableMessageFilterHook)},
6379
+ $message,
6380
+ $reason,
6381
+ $context
6382
+ );
6383
+ return is_string( $filtered_message ) && '' !== $filtered_message ? $filtered_message : $message;
6130
6384
  }
6131
6385
  }
6132
6386
 
6133
6387
  if ( ! function_exists( '${isSupportedFunctionName}' ) ) {
6134
- function ${isSupportedFunctionName}() {
6388
+ function ${isSupportedFunctionName}( array $payload = array(), $cache_result = true ) {
6135
6389
  static $is_supported = null;
6136
- if ( null !== $is_supported ) {
6390
+ $use_cache = $cache_result && count( $payload ) === 0;
6391
+ if ( $use_cache && null !== $is_supported ) {
6137
6392
  return $is_supported;
6138
6393
  }
6139
6394
 
6140
6395
  if ( ! function_exists( 'wp_ai_client_prompt' ) ) {
6141
- $is_supported = false;
6142
- return $is_supported;
6396
+ if ( $use_cache ) {
6397
+ $is_supported = false;
6398
+ }
6399
+ return false;
6143
6400
  }
6144
6401
 
6145
6402
  $schema = ${loadAiSchemaFunctionName}();
6146
6403
  if ( ! is_array( $schema ) ) {
6147
- $is_supported = false;
6148
- return $is_supported;
6404
+ if ( $use_cache ) {
6405
+ $is_supported = false;
6406
+ }
6407
+ return false;
6149
6408
  }
6150
6409
 
6151
6410
  $prompt = wp_ai_client_prompt( 'AI feature support probe.' );
6152
6411
  if ( ! is_object( $prompt ) || ! method_exists( $prompt, 'as_json_response' ) ) {
6153
- $is_supported = false;
6154
- return $is_supported;
6412
+ if ( $use_cache ) {
6413
+ $is_supported = false;
6414
+ }
6415
+ return false;
6416
+ }
6417
+ $prompt_options = ${resolvePromptOptionsFunctionName}( $payload );
6418
+ if (
6419
+ array_key_exists( 'temperature', $prompt_options ) &&
6420
+ null !== $prompt_options['temperature'] &&
6421
+ method_exists( $prompt, 'using_temperature' )
6422
+ ) {
6423
+ $prompt = $prompt->using_temperature( $prompt_options['temperature'] );
6424
+ }
6425
+ if (
6426
+ ! empty( $prompt_options['modelPreference'] ) &&
6427
+ method_exists( $prompt, 'using_model_preference' )
6428
+ ) {
6429
+ $prompt = $prompt->using_model_preference( ...$prompt_options['modelPreference'] );
6155
6430
  }
6156
6431
 
6157
6432
  $structured_prompt = $prompt->as_json_response( $schema );
6158
6433
  if ( ! is_object( $structured_prompt ) ) {
6159
- $is_supported = false;
6160
- return $is_supported;
6434
+ if ( $use_cache ) {
6435
+ $is_supported = false;
6436
+ }
6437
+ return false;
6161
6438
  }
6162
6439
 
6163
6440
  if ( method_exists( $structured_prompt, 'is_supported_for_text_generation' ) ) {
6164
- $is_supported = (bool) $structured_prompt->is_supported_for_text_generation();
6165
- return $is_supported;
6441
+ $supported = (bool) $structured_prompt->is_supported_for_text_generation();
6442
+ if ( $use_cache ) {
6443
+ $is_supported = $supported;
6444
+ }
6445
+ return $supported;
6166
6446
  }
6167
6447
 
6168
- $is_supported = method_exists( $structured_prompt, 'generate_text_result' );
6169
- return $is_supported;
6448
+ $supported = method_exists( $structured_prompt, 'generate_text_result' );
6449
+ if ( $use_cache ) {
6450
+ $is_supported = $supported;
6451
+ }
6452
+ return $supported;
6170
6453
  }
6171
6454
  }
6172
6455
 
@@ -6181,6 +6464,18 @@ if ( ! function_exists( '${adminNoticeFunctionName}' ) ) {
6181
6464
  __( 'The %s AI feature is optional and remains disabled until the WordPress AI Client is available with structured text generation support for the generated schema.', ${quotePhpString(textDomain)} ),
6182
6465
  ${quotePhpString(aiFeatureTitle)}
6183
6466
  );
6467
+ $filtered_message = apply_filters(
6468
+ ${quotePhpString(adminNoticeMessageFilterHook)},
6469
+ $message,
6470
+ array(
6471
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6472
+ 'featureTitle' => ${quotePhpString(aiFeatureTitle)},
6473
+ 'namespace' => ${quotePhpString(namespace)},
6474
+ )
6475
+ );
6476
+ if ( is_string( $filtered_message ) && '' !== $filtered_message ) {
6477
+ $message = $filtered_message;
6478
+ }
6184
6479
  printf( '<div class="notice notice-warning"><p>%s</p></div>', esc_html( $message ) );
6185
6480
  }
6186
6481
  }
@@ -6192,10 +6487,16 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
6192
6487
  return $payload;
6193
6488
  }
6194
6489
 
6195
- if ( ! ${isSupportedFunctionName}() ) {
6490
+ if ( ! ${isSupportedFunctionName}( $payload, false ) ) {
6196
6491
  return new WP_Error(
6197
6492
  'ai_client_unavailable',
6198
- 'The WordPress AI Client is unavailable or does not support this feature endpoint.',
6493
+ ${resolveUnavailableMessageFunctionName}(
6494
+ 'The WordPress AI Client is unavailable or does not support this feature endpoint.',
6495
+ 'support_probe_failed',
6496
+ array(
6497
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6498
+ )
6499
+ ),
6199
6500
  array( 'status' => 501 )
6200
6501
  );
6201
6502
  }
@@ -6209,22 +6510,45 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
6209
6510
  );
6210
6511
  }
6211
6512
 
6513
+ $prompt_options = ${resolvePromptOptionsFunctionName}( $payload );
6212
6514
  $prompt = wp_ai_client_prompt( ${buildPromptFunctionName}( $payload ) );
6213
6515
  if ( ! is_object( $prompt ) ) {
6214
6516
  return new WP_Error(
6215
6517
  'ai_client_unavailable',
6216
- 'The WordPress AI Client prompt builder is unavailable on this site.',
6518
+ ${resolveUnavailableMessageFunctionName}(
6519
+ 'The WordPress AI Client prompt builder is unavailable on this site.',
6520
+ 'prompt_builder_missing',
6521
+ array(
6522
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6523
+ )
6524
+ ),
6217
6525
  array( 'status' => 501 )
6218
6526
  );
6219
6527
  }
6220
6528
 
6221
- if ( method_exists( $prompt, 'using_temperature' ) ) {
6222
- $prompt = $prompt->using_temperature( 0.2 );
6529
+ if (
6530
+ array_key_exists( 'temperature', $prompt_options ) &&
6531
+ null !== $prompt_options['temperature'] &&
6532
+ method_exists( $prompt, 'using_temperature' )
6533
+ ) {
6534
+ $prompt = $prompt->using_temperature( $prompt_options['temperature'] );
6535
+ }
6536
+ if (
6537
+ ! empty( $prompt_options['modelPreference'] ) &&
6538
+ method_exists( $prompt, 'using_model_preference' )
6539
+ ) {
6540
+ $prompt = $prompt->using_model_preference( ...$prompt_options['modelPreference'] );
6223
6541
  }
6224
6542
  if ( ! method_exists( $prompt, 'as_json_response' ) ) {
6225
6543
  return new WP_Error(
6226
6544
  'ai_client_unavailable',
6227
- 'The current WordPress AI Client does not expose as_json_response().',
6545
+ ${resolveUnavailableMessageFunctionName}(
6546
+ 'The current WordPress AI Client does not expose as_json_response().',
6547
+ 'as_json_response_missing',
6548
+ array(
6549
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6550
+ )
6551
+ ),
6228
6552
  array( 'status' => 501 )
6229
6553
  );
6230
6554
  }
@@ -6233,7 +6557,13 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
6233
6557
  if ( ! is_object( $structured_prompt ) ) {
6234
6558
  return new WP_Error(
6235
6559
  'ai_client_unavailable',
6236
- 'The current WordPress AI Client could not prepare a structured-output prompt.',
6560
+ ${resolveUnavailableMessageFunctionName}(
6561
+ 'The current WordPress AI Client could not prepare a structured-output prompt.',
6562
+ 'structured_prompt_missing',
6563
+ array(
6564
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6565
+ )
6566
+ ),
6237
6567
  array( 'status' => 501 )
6238
6568
  );
6239
6569
  }
@@ -6244,14 +6574,26 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
6244
6574
  ) {
6245
6575
  return new WP_Error(
6246
6576
  'ai_client_unavailable',
6247
- 'The current WordPress AI Client provider or model does not support this structured-output feature.',
6577
+ ${resolveUnavailableMessageFunctionName}(
6578
+ 'The current WordPress AI Client provider or model does not support this structured-output feature.',
6579
+ 'text_generation_unsupported',
6580
+ array(
6581
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6582
+ )
6583
+ ),
6248
6584
  array( 'status' => 501 )
6249
6585
  );
6250
6586
  }
6251
6587
  if ( ! method_exists( $structured_prompt, 'generate_text_result' ) ) {
6252
6588
  return new WP_Error(
6253
6589
  'ai_client_unavailable',
6254
- 'The current WordPress AI Client does not expose generate_text_result() after as_json_response().',
6590
+ ${resolveUnavailableMessageFunctionName}(
6591
+ 'The current WordPress AI Client does not expose generate_text_result() after as_json_response().',
6592
+ 'generate_text_result_missing',
6593
+ array(
6594
+ 'featureSlug' => ${quotePhpString(aiFeatureSlug)},
6595
+ )
6596
+ ),
6255
6597
  array( 'status' => 501 )
6256
6598
  );
6257
6599
  }
@@ -6286,7 +6628,7 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
6286
6628
  );
6287
6629
  }
6288
6630
 
6289
- $telemetry = ${buildTelemetryFunctionName}( $result );
6631
+ $telemetry = ${buildTelemetryFunctionName}( $result, $payload, $normalized_result );
6290
6632
  if ( is_wp_error( $telemetry ) ) {
6291
6633
  return $telemetry;
6292
6634
  }
@@ -7165,4 +7507,4 @@ export {
7165
7507
  ADD_BLOCK_TEMPLATE_IDS
7166
7508
  };
7167
7509
 
7168
- //# debugId=DE205F0F5620636264756E2164756E21
7510
+ //# debugId=FE993C1947A36DF464756E2164756E21
@@ -16,7 +16,7 @@ import {
16
16
  escapeRegex,
17
17
  readWorkspaceInventory,
18
18
  resolveEditorPluginSlotAlias
19
- } from "./cli-5md428hf.js";
19
+ } from "./cli-smzkbfna.js";
20
20
  import"./cli-t73q5aqz.js";
21
21
  import {
22
22
  CLI_DIAGNOSTIC_CODES,
@@ -20,7 +20,7 @@ import {
20
20
  snapshotWorkspaceFiles,
21
21
  toPascalCase,
22
22
  updateWorkspaceInventorySource
23
- } from "./cli-5md428hf.js";
23
+ } from "./cli-smzkbfna.js";
24
24
  import {
25
25
  CLI_DIAGNOSTIC_CODES,
26
26
  createCliDiagnosticCodeError
@@ -4,7 +4,7 @@ import {
4
4
  } from "./cli-1sm60g1z.js";
5
5
  import {
6
6
  seedProjectMigrations
7
- } from "./cli-yzmkz95r.js";
7
+ } from "./cli-6hcbjvym.js";
8
8
  import {
9
9
  ensureMigrationDirectories,
10
10
  isPlainObject,
@@ -59,7 +59,7 @@ import {
59
59
  toTitleCase,
60
60
  validateBlockSlug,
61
61
  validateNamespace
62
- } from "./cli-5md428hf.js";
62
+ } from "./cli-smzkbfna.js";
63
63
  import {
64
64
  createManagedTempRoot
65
65
  } from "./cli-t73q5aqz.js";
@@ -12258,7 +12258,9 @@ function createScaffoldCompatibilityConfig(policy) {
12258
12258
  return {
12259
12259
  hardMinimums: capabilityPlan.hardMinimums,
12260
12260
  mode: getPolicyMode(capabilityPlan),
12261
+ optionalFeatureIds: capabilityPlan.optionalFeatures.map((feature) => feature.id),
12261
12262
  optionalFeatures: capabilityPlan.optionalFeatures.map((feature) => feature.label),
12263
+ requiredFeatureIds: capabilityPlan.requiredFeatures.map((feature) => feature.id),
12262
12264
  requiredFeatures: capabilityPlan.requiredFeatures.map((feature) => feature.label),
12263
12265
  runtimeGates: [
12264
12266
  ...capabilityPlan.requiredFeatures.flatMap(formatRuntimeGate),
@@ -17317,6 +17319,6 @@ async function resolveOptionalInteractiveExternalLayerId({
17317
17319
  }
17318
17320
  }
17319
17321
 
17320
- export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, formatNonEmptyTargetDirectoryError, require_semver2 as require_semver, parseTemplateLocator, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
17322
+ export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, formatNonEmptyTargetDirectoryError, require_semver2 as require_semver, parseTemplateLocator, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, createScaffoldCompatibilityConfig, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
17321
17323
 
17322
- //# debugId=9B1DFAD9F6BA017E64756E2164756E21
17324
+ //# debugId=A063D78F028D37F964756E2164756E21