CKEditor AI streaming fails for OpenAI when Guzzle uses StreamHandler for "stream => true" requests
<!-- Please search existing work items before filing to avoid duplicates. --> ## Summary When **AI CKEditor** requests streamed chat from an **OpenAI-based** provider, the request can fail with a generic HTTP 400 (“The request could not be completed.”) while **non-streamed** chat to the same API key and model works. The failure is not caused by missing API credentials or Drupal AI configuration. It occurs on the **streaming code path**: `openai-php`’s `createStreamed()` uses Guzzle `send($request, ['stream' => true])`, which often goes through Guzzle’s default **`StreamHandler`**. This is related in symptom to [#3586425](https://git.drupalcode.org/project/ai/-/work_items/3586425) (CKEditor + streaming), but that issue targets a **provider payload** problem (e.g. Gemini). Here the root cause is **HTTP transport for streamed responses**. ### Proposed fix / notes We confirmed the failure is limited to streamed OpenAI requests. As a **temporary workaround**, forcing Guzzle to use `CurlHandler` site-wide via `$settings['http_client_config']['handler']` in `settings.php` restores CKEditor streaming in our DDEV environment. We would prefer a **fix in the AI module** (or OpenAI provider integration), not a site-wide `settings.php` change, so streaming works without altering Drupal’s default HTTP client for all outbound requests. ## Steps to reproduce 1. Run Drupal on **php-fpm** (e.g. DDEV `nginx-fpm`, PHP 8.3). 2. Install and configure **AI** + **AI Provider: OpenAI** + **AI CKEditor** with a valid OpenAI API key. 3. Confirm **non-streamed** chat works (e.g. AI API Explorer or another operation without streaming). 4. Open a node with a text format using CKEditor 5 + AI plugin; trigger an AI action that streams the response (default CKEditor AI flow uses `setStreamedOutput(TRUE)`). 5. Observe the request to `/api/ai-ckeditor/...` fail. ## Expected result CKEditor receives a **streamed** chat response; tokens appear incrementally; HTTP 200. ## Actual result HTTP **400** with message like **“The request could not be completed.”** Watchdog shows the underlying error, e.g. connection failure when calling OpenAI: ## Environment - Drupal version: 11.3.x (reproduced on 11.3.7) - Module version: drupal/ai 1.3.2, ai_ckeditor (submodule of ai), drupal/ai_provider_openai 1.2.1 - PHP version: 8.3 - Provider: OpenAI (via `OpenAiBasedProviderClientBase` / openai-php client) - Last known working version: n/a (environment-dependent; works when streaming is disabled or when all outbound HTTP is forced through `CurlHandler` site-wide) ### Error messages or logs Error invoking model response: Connection refused for URI https://api.openai.com/v1/chat/completions
issue