Skip to content

Fix AI credentials detection#537

Open
LukasFritzeDev wants to merge 2 commits into
WordPress:developfrom
LukasFritzeDev:fix/has_ai_credentials-env-constant
Open

Fix AI credentials detection#537
LukasFritzeDev wants to merge 2 commits into
WordPress:developfrom
LukasFritzeDev:fix/has_ai_credentials-env-constant

Conversation

@LukasFritzeDev
Copy link
Copy Markdown

@LukasFritzeDev LukasFritzeDev commented May 12, 2026

What?

Closes #536

  • add shared API key detection that checks environment variables, PHP constants, and stored settings
  • use the shared detection for both the credentials helper and dashboard widget connection state

Why?

if the provider API key is set up using constant in wp-config.php or an ENV (instead of providing the key via the connectors settings page)

  • Settings › AI shows an error saying “The AI plugin requires a valid AI Connector to function properly.”
  • the Dashboard widget shows ❌ instead of ✅ for the connector

How?

  • Add helper function has_api_key_configured that checks environment variable, PHP constant and database option.
  • Use the helper in has_ai_credentials and AI_Status_Widget to get the correct state information

Use of AI Tools

AI assistance: Yes
Tool(s): IDE Code completion
Model(s): Devstral-Small-2-24B-Instruct-2512
Used for: IDE Code completion

Testing Instructions

Screenshots or screencast

Before After
591160483-e9897f93-659f-4934-843e-409e63390d42 No error
Bildschirmfoto 2026-05-12 um 20 23 00 Bildschirmfoto 2026-05-12 um 20 42 29

Changelog Entry

Fixed connector status in settings page an dashboard widget if key is configured using env or constant

Open WordPress Playground Preview

…le, PHP constant and database value

This fixes the invalid error on the AI settings page. Before this only the database option value was checked when evaluating if an API key is set. This introduces the helper `has_api_key_configured` that also checks for env value or PHP constant. If one of the values is set, the helper returns true.
This fixes the state display o a connector in the dashboard widget if the API key is configured using a env or a constant by using the new helper function `has_api_key_configured`
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 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: LukasFritzeDev <lukasfritzedev@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: justlevine <justlevine@git.wordpress.org>
Co-authored-by: gziolo <gziolo@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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 0% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.57%. Comparing base (27ac41f) to head (5c0aafa).

Files with missing lines Patch % Lines
includes/helpers.php 0.00% 14 Missing ⚠️
includes/Admin/Dashboard/AI_Status_Widget.php 0.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #537      +/-   ##
=============================================
- Coverage      70.72%   70.57%   -0.16%     
+ Complexity      1144     1143       -1     
=============================================
  Files             67       67              
  Lines           5510     5522      +12     
=============================================
  Hits            3897     3897              
- Misses          1613     1625      +12     
Flag Coverage Δ
unit 70.57% <0.00%> (-0.16%) ⬇️

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.

@LukasFritzeDev
Copy link
Copy Markdown
Author

I’m not sure how to test this in the e2e tests. Sure, we could add a test spec for this, but this would require to set the config value in .wp-env.test.json and this would break other tests. Should set up an additional env with the value and run a seperate test script for this? Do you have any other ideas?

@justlevine
Copy link
Copy Markdown
Contributor

I’m not sure how to test this in the e2e tests.... Do you have any other ideas?

I don't think we need explicit e2e testing for this, since the outcome - behavior when there are/arent creds - hasn't changed. What's changing here is the internal handling for where credentials can be sourced from, so PHPUnit (Integration) testing should be enough IMO.

@gziolo
Copy link
Copy Markdown
Member

gziolo commented May 12, 2026

Why don't you check directly on the AI provider instance whether it's configured? The connectors for AI providers gets registered automatically based on the info stored in AI provider registry. In fact, the names for the env variable and PHP constant are standardized there.

@dkotter
Copy link
Copy Markdown
Collaborator

dkotter commented May 12, 2026

I’m not sure how to test this in the e2e tests. Sure, we could add a test spec for this, but this would require to set the config value in .wp-env.test.json and this would break other tests. Should set up an additional env with the value and run a seperate test script for this? Do you have any other ideas?

I agree with @justlevine here that we don't really need an E2E test for this. That said, we do load a test plugin in our test environment and so you could use that to help with this. As an example of something I've done before, you could add something like this in the e2e-request-mocking.php file:

// Set the OpenAI API key as a constant when override param is set.
add_action(
	'init',
	static function () {
		if (
			isset( $_GET['ai_api_key_override'] ) &&
			! defined( 'OPENAI_API_KEY' )
		) {
			define( 'OPENAI_API_KEY', 'valid-api-key' );
		}
	},
	1
);

And then in your E2E test, do the following:

  1. Remove credentials from OpenAI
  2. Go to the settings page and ensure the admin notice shows
  3. Refresh the settings page with the query param ai_api_key_override added
  4. Ensure the admin notice no longer shows

Could then replicate this for the dashboard widget

@dkotter
Copy link
Copy Markdown
Collaborator

dkotter commented May 12, 2026

Why don't you check directly on the AI provider instance whether it's configured? The connectors for AI providers gets registered automatically based on the info stored in AI provider registry. In fact, the names for the env variable and PHP constant are standardized there.

@gziolo Not sure I completely follow? Is this around the question about E2E tests? Or a suggestion on how the code in this PR could be better? Need to do a full review but in looking quickly, does look like it pulls the env and constant name from the Connector Registry.

As far as I know though, that registry doesn't tell us if a Connector is actually configured. Let me know if that's not correct though.

EDIT: Reading again, I think what you're referring to is the AI Client Registry, not the Connectors Registry. In that case I do think we can use that instead though it's not super different from the approach taken here

Comment thread includes/helpers.php
* @param array{setting_name?: string, env_var_name?: string, constant_name?: string} $auth Authentication configuration.
* @return bool True if an API key is set by one of the configuration options, false otherwise.
*/
function has_api_key_configured( array $auth ): bool {
Copy link
Copy Markdown
Collaborator

@dkotter dkotter May 12, 2026

Choose a reason for hiding this comment

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

Based on feedback from @gziolo and looking at things closer, a different approach we can take here is using the AI Client Registry. I'm not super opinionated either way as Core itself uses both approaches but it is slightly less code This is likely the better approach as I think about it more, see https://github.com/WordPress/wordpress-develop/blob/88612f5798c7ec0d2d94044114a2f1e8fe111897/src/wp-includes/connectors.php#L692-L697

$registry        = AiClient::defaultRegistry();
$connectors      = get_ai_connectors();
$has_credentials = false;

foreach ( $connectors as $connector_id => $connector_data ) {
    if (
		! $registry->hasProvider( $connector_id ) ||
		! $registry->isProviderConfigured( $connector_id )
	) {
		continue;
	}

    $has_credentials = true;
    break;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only looked briefly, but ::isProviderConfigured() also seems more future-compat and likely to stay robust enough for whatever Connector changes come in WP7.1.

@dkotter dkotter added this to the 1.0.0 milestone May 12, 2026
@gziolo
Copy link
Copy Markdown
Member

gziolo commented May 12, 2026

@dkotter, I'm talking about production code and the fact that AI providers need to be configured before they get discovered by the connectors registry. Even when the AI provider uses db setting, it's the connector that sets everything on the AI provider instance. See:

https://github.com/WordPress/wordpress-develop/blob/7938204d20159fa863e6d34af352bb7557524354/src/wp-includes/connectors.php#L626

@dkotter
Copy link
Copy Markdown
Collaborator

dkotter commented May 12, 2026

the fact that AI providers need to be configured before they get discovered by connectors registry. Even, when the AI provider uses db setting, it's the connector that sets everything on the AI provider insrance.

I think we're saying the same things, apologize for the back and forth (see my comment here on recommended changes that I think matches what you're saying).

If we just use wp_get_connectors, it never tells us what connectors are actually configured. But yes, if we use AiClient::defaultRegistry, that should only give us AI providers that have been configured. I'd argue this is more confusing than it needs to be and maybe having a is_configured key as part of the data wp_get_connectors returns would be nice but regardless, we can work around that here with a better approach than we currently have

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.

has_ai_credentials returns false if key is configured via constant

4 participants