Issue #3586446: Add per-provider HTTP handler configuration

Description

Adds per-provider HTTP client handler configuration so sites can fix streaming failures (e.g. OpenAI + CKEditor AI under php-fpm/Docker) without site-wide $settings['http_client_config']. Previously, AiProviderClientBase::create() accepted http_client_options on plugin construction, but nothing set it. This MR introduces AiProviderHttpClientOptionsBuilder, which merges:

  1. Exported config (ai.settings:provider_http_clients)
  2. settings.php ($settings['ai_provider_http_clients'])
  3. Explicit http_client_options on createInstance() (highest priority) Handler presets: | Preset | Effect | |--------|--------| | default | No override — current Drupal HTTP client behaviour | | curl | HandlerStack::create(new CurlHandler()) for that provider only | UI: Advanced settings » Provider HTTP clients — one select per installed provider. Docs: docs/developers/provider_http_client.md Tests: tests/src/Unit/Service/AiProviderHttpClientOptionsBuilderTest.php; kernel schema coverage updated. Closes #3586446

Testing instructions

  1. Enable AI and an OpenAI provider module; configure a valid API key.
  2. Go to /admin/config/ai/settingsAdvanced settingsProvider HTTP clients.
  3. Confirm each provider shows Default (Drupal HTTP client) by default; save — provider_http_clients should stay empty.
  4. Set OpenAI to cURL handler, save, and confirm ai.settings:provider_http_clients.openai.handler is curl.
  5. On an environment where streamed CKEditor AI failed with default handler, confirm streaming works with OpenAI set to cURL handler (no site-wide http_client_config change).
  6. Optional: in settings.php, set $settings['ai_provider_http_clients']['openai'] = ['handler' => 'curl']; — confirm the UI field is disabled and the override applies.
  7. Run unit tests:
    cd web/core
    ../vendor/bin/phpunit -c phpunit.xml.dist \
      ../modules/contrib/ai/tests/src/Unit/Service/AiProviderHttpClientOptionsBuilderTest.php
    

Checklist

  • I have linked the related issue in the MR title or description
  • I have performed a self-review of my own code
  • I have added or updated tests, or explained in the description why this change is not covered by tests
  • I have updated documentation for any new or changed functionality
  • I have written testing instructions and verified them locally
  • I have noted any required post-merge steps (config imports, cache rebuilds, manual changes)
  • This MR contains no breaking API or hook changes, or they are explicitly documented in the description

AI Compliance

Note

Check the one that best describes your usage, or leave all unchecked if AI was not significantly used.

  • AI Assisted Code
    Mainly written by a human; AI used for autocomplete or partial generation under full human supervision.

  • AI Generated Code
    Mainly generated by AI, reviewed and approved by a human before this MR was created.

  • Vibe Coded
    Generated by AI and only functionally reviewed before this MR was created.

Closes #3586446

Merge request reports

Loading