Skip to content

Conversation

@dkotter
Copy link
Collaborator

@dkotter dkotter commented Jan 26, 2026

Description of the Change

Warning

Apologies in advance for the large size of this PR. I kept finding things that needed adding or adjusting to get everything working properly, though there are lots of minor changes here like file renaming or moving code around.

I don't think there's a clean way to break this into multiple PRs and have each of those be good testable chunks but code review could be handled on those smaller PRs and then actual testing could be done here if that is more desirable

At the moment, the workflow in ClassifAI is to go into a Feature, choose the Provider you want for that Feature and enter in any Provider credentials from within that Feature. There's nothing wrong with this approach but it does require you to enter your credentials again for each Feature that you want to use the same Provider for (which is likely the majority of use cases).

This has been a common request (to simplify how Providers are setup) and we've also gotten quite a few recent requests around making it easier to programmatically manage credentials (for instance, setting those up as constants in wp-config.php instead of having to enter those in the UI and have those saved to your database).

This PR attempts to address both of these by introducing the concept of global Providers, while still retaining the ability to override credentials at the Feature-level if desired (and to help maintain backwards-compat).

At a high-level, this is what has been done:

  • Introduce a new Providers settings tab that renders out all Providers with their required credential fields
  • Refactor the components that render these credentials so they can be used both on this new global Providers page and within the individual Features
  • Introduce new classes that help manage Provider profiles and configs, as well as a central place to verify credentials
  • Introduce a new CredentialResolver class that will determine where to pull credentials from (either the global scope or the Feature-scope)
  • Add new methods on the Provider class that get all credentials for that Provider or a specific credential field. These all pass through a new filter (classifai_provider_credentials) making it easy for other to hook in and change those credentials
  • At the Feature-level, add a new Override toggle that allows you to use Feature-level Provider credentials. For new installs, this defaults to being off and thus all Features by default will use global credentials. For existing installs, all Features are considered to be overridden and will use the existing Feature-level credentials, though we show prompts in these situations so users can migrate to global credentials if they desire
  • Remove the unneeded Credential Reuse code as we aren't sharing credentials anymore
  • More standardization on how API requests are made, making it easier to ensure all credentials pass through our new filter and setting us up for the future where we will integrate the new WP AI Client for these requests
  • General refactoring / code cleanup to account for this new architecture. I tried to keep this to a minimum as this PR is already quite large but some of this was necessary and some felt like the right thing /right time to do

Screenshots

New Providers setting screen Feature settings screen with new override credentials toggle turned off Feature settings screen with new override credentials toggle turned on

How to test the Change

This is a fairly global change and as such, testing multiple Feature / Provider combinations is the ideal. In addition, testing Features with overridden credentials and Features with global credentials is ideal.

Changelog Entry

Added - Ability to set Providers at a global level, allowing you to easily re-use Provider credentials across all Features that need them
Added - New setting that allows you to override Provider credentials at the Feature-level. For any existing sites that have set up ClassifAI, your Features will be considered to be in an override state but you can migrate credentials to the new global scope as desired
Added - New filter, classifai_provider_credentials, that allows developers the ability to override AI credentials prior to those being used
Changed - For filters that run when API requests are made, the Feature name, not the Feature option name is now passed as an argument. If you have code that relies on that argument, updates will be needed
Removed - Credential re-use code has been removed as it is no longer needed

Credits

Props @dkotter, @fabiankaegy

Checklist:

…undation)

- ProviderProfiles: registry mapping provider IDs to vendor profiles and
  credential fields; supports grouped and ungrouped profiles.
- ProviderConfigStore: persistence for global provider configs in
  classifai_provider_configs option.
- CredentialResolver: resolves effective credentials, preferring
  feature-level overrides over global config.
…onfigs

- ProviderProfiles, ProviderConfigStore, CredentialResolver: registry,
  storage, and resolution for global provider credentials (override-aware).
- GET/POST /classifai/v1/provider-configs: list profiles and configs,
  update config per profile. Plain-string labels in ProviderProfiles to
  avoid static initializer errors.
- Providers tab: fetch provider-configs, list profiles with Configured /
  Not configured / No configuration needed. Redux: providerProfiles,
  providerConfigs, actions, selectors. Route and styles for Providers.
…ices

- Feature: merge CredentialResolver into get_settings; sanitize override.
- CredentialResolver: explicit override (true=Feature, false=global); infer from non-empty creds when unset.
- ClassifAISettings: fetch provider-configs on load.
- ProviderSettings: notices to configure in Providers tab or use Feature-level creds.
- utils: getProfileForProvider, hasFeatureLevelCredentials
- Delete CredentialReuse helper and credential-reuse/(feature_id), credential-reuse/copy REST routes.
- Remove CredentialReuseModal and its usage from ServiceSettings and EnableToggleControl.
- Remove credential-reuse SCSS and Cypress modal commands/tests.
- ProviderProfileForm with inputs per credential_fields, Save wired to POST /provider-configs
- ProviderCredentialsVerifier for OpenAI and Ollama; set authenticated and verification_error
- Status (Verified / Not configured) only when config.authenticated === true
- ProviderSettings: links to Providers tab and isProviderConfigured with global configs
…entials or an individual credential and pass that through a filter so others can change credentials if desired. Minor modifications to our CredentialResolver to only return credentials, not all Feature-Provider settings. Remove unneeded code from the Feature class
…tance and we use that to get the API key, passing through our new credential filtering. Ensure we can pass settings to our credential filtering and use those if passed instead of using the saved credentials. Allows us to filter credentials when settings are being saved.
… the Feature ID to avoid extra code duplication
@dkotter dkotter added this to the 3.8.0 milestone Jan 26, 2026
@dkotter dkotter self-assigned this Jan 26, 2026
@github-actions
Copy link

github-actions bot commented Jan 26, 2026

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

…sticPress by default and we also disable the admin bar changes ElasticPress makes as it seems that causes issues
@github-actions github-actions bot added the needs:refresh This requires a refreshed PR to resolve. label Jan 27, 2026
@github-actions github-actions bot removed the needs:refresh This requires a refreshed PR to resolve. label Jan 27, 2026
@jeffpaul jeffpaul moved this to In Progress in Open Source Practice Jan 27, 2026
  - Include providerProfiles and providerConfigs in inline script data,
    eliminating a separate API call on initial page load
  - Add user-facing error notice in ProvidersSettings when loading fails
  - Add fallback API fetch only when profiles are empty (edge cases)
  - Display informative message when no Provider profiles are available
@dkotter dkotter marked this pull request as ready for review January 29, 2026 17:30
@dkotter dkotter requested review from a team and jeffpaul as code owners January 29, 2026 17:30
@github-actions github-actions bot added the needs:code-review This requires code review. label Jan 29, 2026
@dkotter dkotter requested review from peterwilsoncc and removed request for a team and jeffpaul January 29, 2026 17:30
@jeffpaul jeffpaul moved this from In Progress to Code Review in Open Source Practice Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs:code-review This requires code review.

Projects

Status: Code Review

Development

Successfully merging this pull request may close these issues.

1 participant