The cmd-features plugin exposes the filter hooks below so a theme or companion plugin can adjust its behaviour without forking it. Register callbacks with add_filter() from your theme's functions.php.
Several of these filters run on values that are printed to the page. A callback that returns unescaped, attacker-influenced markup will introduce a cross-site scripting hole. Escape whatever you return.
Retrieval and AI responses
cmd_ai_connector_supports_service_tier
Filters whether a connector accepts OpenAI's service_tier parameter, which is how CMOPT_AI_PRIORITY is applied. Only the openai connector does by default: custom options are merged verbatim into the provider's request body, and a provider that rejects unknown fields would fail every first attempt. Return true for an OpenAI-compatible gateway registered under a different connector ID.
$supportedbool- Whether the parameter may be sent. True only for openai by default.
$providerstring- Connector ID the request is going to.
add_filter( 'cmd_ai_connector_supports_service_tier', function ( $supported, $provider ) {
return 'my-openai-gateway' === $provider ? true : $supported;
}, 10, 2 );cmd_ai_connector_require_listed_model
Filters whether a connector request needs a model the provider lists. By default a CMOPT_AI_CONNECTOR_MODEL value the provider does not list for text generation is refused before any request is sent, and the error log names the listed ID to use instead. Without this check the WordPress AI client silently answers with the first model the provider lists, which on Anthropic is its most expensive. Return false to allow that fallback.
$requiredbool- Whether the model must be listed. True by default.
$providerstring- Connector ID the request is going to.
$modelstring- The model requested.
add_filter( 'cmd_ai_connector_require_listed_model', function ( $required, $provider ) {
return 'my-gateway' === $provider ? false : $required;
}, 10, 2 );cmd_ai_connector_custom_options
Filters the provider-specific parameters sent with a connector generation. The WordPress AI layer models only the settings every provider shares, so anything provider-specific — OpenAI's service_tier, which is how CMOPT_AI_PRIORITY is applied — travels through here and is merged verbatim into the provider's request body. Keys must be ones that provider accepts.
$optionsarray- Provider-specific parameters. Contains service_tier when CMOPT_AI_PRIORITY is enabled and the connector accepts it.
$argsarray- The generation arguments, including context and max_tokens.
$providerstring- Connector ID the request is going to. Appended third so that callbacks registered against the original two-argument signature keep working.
add_filter( 'cmd_ai_connector_custom_options', function ( $options ) {
$options['reasoning'] = array( 'effort' => 'low' );
return $options;
} );cmd_ai_connector_provider
Filters which WordPress 7.0 Connector answers an AI request, after CMOPT_AI_PROVIDER has been resolved. Return an empty string to force the plugin's own OpenAI HTTP request instead. Useful for routing features to different providers — a cheap model for search summaries, a stronger one for suggested replies.
$providerstring- Resolved connector ID, or an empty string when the legacy OpenAI path will be used.
$contextstring- What the text is for: rag, cf7, or an empty string when unspecified.
$preferencestring- The stored CMOPT_AI_PROVIDER value.
add_filter( 'cmd_ai_connector_provider', function ( $provider, $context ) {
return 'cf7' === $context ? 'anthropic' : $provider;
}, 10, 2 );cmd_format_post_data
Filters the Markdown context block built from a single post before it is sent to the model. Use it to add or remove fields from the retrieved context.
$formatted_itemstring- The formatted context block, by default a Markdown heading followed by the post content.
$post_idint- ID of the post the block was built from.
add_filter( 'cmd_format_post_data', function ( $item, $post_id ) {
return $item . "\n\nURL: " . get_permalink( $post_id );
}, 10, 2 );cmd_rag_visible_taxonomy
Filters the taxonomy label displayed before a search result link. Returns an empty string by default, which hides the label.
$taxonomy_labelstring- Label to display. Empty by default.
$postWP_Post- The post being rendered as a result.
cmd_rag_source_block
Filters the delimited <source> block for one retrieved post before it enters the prompt. The block carries the post ID the model cites the source by, so a filter that rewrites it must leave the id attribute intact.
$blockstring- The formatted <source> element, including its title and content.
$postWP_Post- The post the block was built from.
cmd_ai_managed_option_hosts
Filters the host suffixes whose AI option defaults the plugin manages. commandmedia.net environments are on this list, which is what moves them to a new default (such as the retrieval depth of 6) on deploy; a client install matches nothing and keeps its saved values. Append a suffix to opt a local or staging copy in.
$hostsstring[]- Lowercase host suffixes, matched against the site host and its subdomains.
cmd_rag_rest_source
Filters one source entry before it is returned by the REST answer endpoint. Since 2.9.0 the entries are the sources the model reported using, not everything retrieval returned. Use it to add fields such as an excerpt or a featured image URL.
$source_entryarray- Source entry containing title, url and id keys. id is the source identifier the model cited, e.g. post:123.
$postWP_Post- The post the entry was built from.
cmd_filter_response
Filters the sanitised AI answer immediately before output. This is the last chance to rewrite, truncate or replace the answer.
$safe_answerstring- The sanitised answer text.
$wp_display_resultsarray- Citation link markup for the sources the answer was built from. Empty when the answer cited none, in which case no list is rendered.
cmd_ai_response_heading_text
Filters the heading shown above an AI response. Defaults to "AI Response".
$heading_textstring- The heading text.
cmd_ai_response_disclaimer_text
Filters the disclaimer shown inside the AI response wrapper. Defaults to "AI can make mistakes. Please double-check responses."
$disclaimer_textstring- The disclaimer text.
ChatKit
cmd_chatkit_search_max_results
Filters how many results the ChatKit site_search tool may return. The filtered value is clamped to between 1 and 10, so a filter cannot widen the tool beyond its safe bounds.
$max_resultsint- Value of CMOPT_AI_CHATKIT_SEARCH_MAX_RESULTS, 3 by default.
cmd_chatkit_search_max_chars
Filters the character budget for the ChatKit site_search payload. The filtered value is clamped to between 500 and 200000.
$max_charsint- Value of CMOPT_AI_CHATKIT_SEARCH_MAX_CHARS, 24000 by default.
Contact Form 7 suggested replies
cmd_cf7_ai_skip_inquiry_field
Filters whether a submitted Contact Form 7 field is treated as noise and excluded from the enquiry context. Honeypots, mc4wp fields and auto-numbered field names are skipped by default.
$skipbool- Whether the field will be skipped.
$keystring- The submitted field name.
add_filter( 'cmd_cf7_ai_skip_inquiry_field', function ( $skip, $key ) {
return 'internal-ref' === $key ? true : $skip;
}, 10, 2 );cmd_cf7_ai_inquiry_field_label
Filters the human-readable label a Contact Form 7 field is given in the enquiry context. Known field names are mapped; anything else is title-cased.
$labelstring- The resolved display label.
$keystring- The submitted field name.
Option lifecycle
cmd_deprecated_option_names
Filters the list of retired option names deleted by the cleanup routine. Add any site-specific option names that should be purged from the options table. Deletion is idempotent and runs once per plugin version bump.
$namesstring[]- Option names slated for deletion.
add_filter( 'cmd_deprecated_option_names', function ( $names ) {
$names[] = 'CMOPT_MY_RETIRED_OPTION';
return $names;
} );Settings screen
The settings screen renders itself from the options documentation file. These filters adjust how it reads that file and how it groups what it finds.
cmd_cmopt_field_spec
Filters one option's specification immediately before its field is rendered. Applied at render time rather than when the registry is built, so an option whose choices come from runtime state can supply them — CMOPT_AI_PROVIDER uses it to become a dropdown of the AI connectors WordPress currently reports, which a static list in the options file could not describe without going stale.
$specarray- Option specification: name, title, type, description, summary, default, choices, section.
add_filter( 'cmd_cmopt_field_spec', function ( $spec ) {
if ( 'CMOPT_AI_CONNECTOR_MODEL' === $spec['name'] ) {
$spec['type'] = 'select';
$spec['choices'] = my_model_list();
}
return $spec;
} );cmd_cmopt_registry_path
Filters the absolute path of the JSON file describing the options. An option that file does not describe is not rendered on the settings screen, so this filter effectively controls which options are editable.
$pathstring- Absolute path to the options documentation file.
cmd_cmopt_sub_namespaces
Filters the name segments treated as a sub-system when the settings screen derives its sections. A segment listed here splits its options into their own section, so CMOPT_AI_CF7_* fields group separately from the rest of the AI options rather than collapsing into one long list.
$tokensstring[]- Uppercase name segments, CF7 and CHATKIT by default.
add_filter( 'cmd_cmopt_sub_namespaces', function ( $tokens ) {
$tokens[] = 'MYFEATURE';
return $tokens;
} );cmd_cmopt_section_labels
Filters the display titles of the settings sections. A section with no entry here is title-cased from its name segment, so a new group gets a readable heading without any code change.
$labelsarray- Map of section key to display title.
