Skip to content

Add extensibility hooks for system instructions, ability results, and post context#304

Open
Ryujiyasu wants to merge 2 commits intoWordPress:developfrom
Ryujiyasu:feat/hook-audit-extensibility-hooks
Open

Add extensibility hooks for system instructions, ability results, and post context#304
Ryujiyasu wants to merge 2 commits intoWordPress:developfrom
Ryujiyasu:feat/hook-audit-extensibility-hooks

Conversation

@Ryujiyasu
Copy link

@Ryujiyasu Ryujiyasu commented Mar 13, 2026

Summary

Implements the extensibility hooks agreed upon in the #34 hook audit discussion with @dkotter.

New Filters

1. System Instruction Filter (Abstract_Ability)

  • ai_experiments_system_instruction — Filters the system instruction text before it's passed to the AI model. Receives the instruction string, ability name, and data array.

2. Ability Result Filters (Abstract_Ability)

  • ai_experiments_ability_result — Generic filter applied to the result of any ability execution. Receives the result, ability name, and input.
  • ai_experiments_ability_result_{$name} — Dynamic filter for a specific ability (e.g., ai_experiments_ability_result_ai/title-generation). Receives the result and input.

3. Post Context Filters (in the Abilities, per discussion)

  • ai_experiments_get_post_details — Filters post details returned by the ai/get-post-details ability. Receives details array, post ID, and requested fields.
  • ai_experiments_get_post_terms — Filters terms returned by the ai/get-post-terms ability. Receives terms array, post ID, and allowed taxonomies.

Design Decisions

  • Result filtering is implemented via a filtered_execute_callback wrapper in Abstract_Ability that wraps the abstract execute_callback. This avoids requiring changes to every concrete ability class while ensuring all abilities get consistent filtering.
  • WP_Error results are not filtered — errors pass through unmodified.
  • Post context filters are in the Abilities only (not in get_post_context helper), as agreed with @dkotter.

Example Usage

// Modify system instructions for all abilities.
add_filter( 'ai_experiments_system_instruction', function( $instruction, $name, $data ) {
    return $instruction . "\n\nAlways respond in formal tone.";
}, 10, 3 );

// Filter title generation results.
add_filter( 'ai_experiments_ability_result_ai/title-generation', function( $result, $input ) {
    // Remove any titles that are too long.
    if ( is_array( $result ) ) {
        $result = array_filter( $result, fn( $title ) => strlen( $title ) <= 100 );
    }
    return $result;
}, 10, 2 );

// Redact sensitive fields from post details before AI processing.
add_filter( 'ai_experiments_get_post_details', function( $details, $post_id, $fields ) {
    unset( $details['author'] );
    return $details;
}, 10, 3 );

Closes #34

Test Plan

  • Verify existing ability tests still pass
  • Verify ai_experiments_system_instruction filter modifies system instructions
  • Verify ai_experiments_ability_result filter modifies ability results
  • Verify ai_experiments_get_post_details filter modifies post details
  • Verify ai_experiments_get_post_terms filter modifies post terms
  • Verify WP_Error results are not filtered
Open WordPress Playground Preview

… post context

Adds filters agreed upon in WordPress#34 hook audit discussion:

- `ai_experiments_system_instruction` in Abstract_Ability::get_system_instruction()
- `ai_experiments_ability_result` and `ai_experiments_ability_result_{$name}` for filtering ability execution results
- `ai_experiments_get_post_details` in get-post-details ability
- `ai_experiments_get_post_terms` in get-post-terms ability
@github-actions
Copy link

github-actions bot commented Mar 13, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: Ryujiyasu <ryujiyasu@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Tests cover:
- ai_experiments_system_instruction filter modifies instructions
- ai_experiments_system_instruction filter receives correct ability name
- ai_experiments_ability_result filter modifies results
- ai_experiments_ability_result_{$name} dynamic filter works
- WP_Error results bypass filtering
@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.19%. Comparing base (f2b29e6) to head (28a2cf3).

Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #304      +/-   ##
=============================================
+ Coverage      58.03%   58.19%   +0.15%     
- Complexity       576      578       +2     
=============================================
  Files             37       37              
  Lines           2955     2966      +11     
=============================================
+ Hits            1715     1726      +11     
  Misses          1240     1240              
Flag Coverage Δ
unit 58.19% <100.00%> (+0.15%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jeffpaul jeffpaul requested a review from dkotter March 13, 2026 15:07
@jeffpaul jeffpaul added this to the 0.6.0 milestone Mar 13, 2026
@gziolo
Copy link
Member

gziolo commented Mar 16, 2026

The plugin is being renamed in #287 by @dkotter. There is a related feedback #287 (review) from @jeffpaul, which makes perfect sense here as well:

Imay want to consider updating other parts of the codebase to remove experiment-named items to make things simpler to maintain in the future even if that's a backcompat break (as generally something that would be easier to do before 7.0 than after).

This applies to the names of the proposed hooks. Let's finalize the naming conventions here. Also note that in WP core, all AI related hooks are prefixed with wp_.

@gziolo
Copy link
Member

gziolo commented Mar 16, 2026

Thanks for working on this, @Ryujiyasu! I'm very much in favor of adding extensibility filters — this is exactly the kind of developer control the plugin needs.

However, after reviewing this alongside prior work on the Abilities API, I think some of these filters would be better suited for WP core rather than the plugin. Here's my analysis:

Filters that should go to WP core

WP core already fires wp_after_execute_ability in WP_Ability::execute(), but as an action — not a filter — so developers can observe results but can't modify them. A core-level result filter would close that gap for all abilities.

ai_experiments_ability_result and ai_experiments_ability_result_{$name}

These are generic "filter the result of any ability execution" hooks — not AI-specific. The same concept was proposed in the Abilities API repo in the early phase of development:

Placing result filtering in core (inside WP_Ability::execute()) would be better because:

  1. It applies to all abilities, not just those extending Abstract_Ability from this plugin.
  2. It sits in the proper lifecycle — after do_execute(), integrated with output validation — rather than requiring the filtered_execute_callback workaround that adds a public method as an implementation detail.
  3. It avoids the current issue where filtered results that don't conform to the ability's output schema will cause validate_output() to fail silently.
  4. The relationship between result filters and the existing core action wp_after_execute_ability needs to be designed intentionally at the core level, so developers know whether they receive the original result or a filtered one.

Now that Abilities API development has moved to core, these filters should be proposed there. I'd be happy to help with that.

Filters that belong in this plugin

ai_experiments_system_instruction — This is plugin-specific (system instructions are an AI concept with no core equivalent). Looks good as-is.

ai_experiments_get_post_details / ai_experiments_get_post_terms — These filter data within plugin-specific utility abilities, or could they be also superseeded by filters added directly?

/**
* Filters the post details returned by the get-post-details ability.
*
* @since 0.5.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace all @since statements with x.x.x as we're not sure of the actual version until we prep a release (and we have a step in our release process to find and replace all of those)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit Codebase for Strategic Hook Opportunities

4 participants