Make WordPress Core

Opened 5 weeks ago

Last modified 4 weeks ago

#65097 new feature request

Add action to `WP_AI_Client_Prompt_Builder` for builder-level configuration injection

Reported by: takshil's profile takshil Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: AI Keywords: 2nd-opinion has-patch
Focuses: Cc:

Description

Problem

Currently, model selection happens in one of two places:

  1. Inside the SDK / connector - provider-default model ordering. Its useful but provider-scoped, cannot express cross-provider preferences like "use OpenAI for text, Mistral for images."
  2. Inside each consumer plugin - hardcoded using_model_preference( 'gpt-5.4', 'claude-sonnet-4-6' ). Fragmented, opaque to site owners, no shared coordination.

There is no third place - no site-owner-controlled layer that applies across all consumer plugins. A standalone "preferences" plugin can store the user's choices but has no way to inject them into builders constructed elsewhere, because no construction time hook exists.

Proposed solution

Add one action at the end of WP_AI_Client_Prompt_Builder::__construct(), immediately after the existing default-timeout block:

<?php
// In wp-includes/ai-client/class-wp-ai-client-prompt-builder.php

/**
 * Fires after a prompt builder is constructed, before any caller chaining.
 *
 * Allows plugins to apply default configuration that callers can still override via subsequent
 * fluent method calls. Because this fires at construction, any chain applied
 * by the caller takes precedence per the SDK's first-match resolution.
 *
 * @since 7.x.0
 *
 * @param WP_AI_Client_Prompt_Builder $builder The newly constructed builder.
 * @param mixed                       $prompt  The initial prompt content.
 */
do_action_ref_array( 'wp_ai_client_prompt_builder_init', array( $this, $prompt ) );

Caller precedence is automatic

1. Core constructs builder
2. wp_ai_client_default_request_timeout fires → sets timeout
3. wp_ai_client_prompt_builder_init fires → preferences plugin chains
   ->using_model_preference('gpt-5.4', 'mistral-image-v1', ...)
4. Builder returns to the caller
5. Caller chains its own potentially by a plugin allowing user's preferences
   to be set with a UI->using_model_preference('claude-sonnet-4-6').
   Could be a separate plugin for now, I have some ideas.
6. SDK's first-match resolution at generate_*() time picks the first model
   that (a) supports the requested capability and (b) has credentials.
   The caller's explicit preference wins because it's evaluated first.

Why an Action?

It comes down to what listeners will dominantly do:

  • Mutate via ->using_model_preference() chains → action is the cleaner fit (no return tax, natural accumulation)
  • Replace/decorate the builder → filter is required

Going towards pre_get_posts precedent. Core's go-to hook for "mutate a fluent/builder-like object" is an action, not a filter, precisely because filtering a stateful mutable object invites bugs. This is the closest analog I thought of in core. Though open to discussion for filter if the AI team prefers consistency with the existing two filters in this file

Discussion

Attachments (2)

wp-ai-client-prompt-builder-init.patch (1.2 KB) - added by takshil 5 weeks ago.
Patch for the proposed action.
65097.patch (1.5 KB) - added by sachinrajcp123 5 weeks ago.

Download all attachments as: .zip

Change History (4)

@takshil
5 weeks ago

Patch for the proposed action.

This ticket was mentioned in Slack in #core-ai by takshil. View the logs.


5 weeks ago

#2 @takshil
4 weeks ago

@JeffPaul @raftaar1191 created this ticket for implementing https://core.trac.wordpress.org/ticket/65115#ticket

My idea is to create a separate plugin to test the waters around this by introducing a filter for now.

Note: See TracTickets for help on using tickets.