Skip to content

Add AI Client connector (XWPENG-20) - #1967

Open
shadyvb wants to merge 4 commits into
developfrom
feature/add-ai-client-connector
Open

Add AI Client connector (XWPENG-20)#1967
shadyvb wants to merge 4 commits into
developfrom
feature/add-ai-client-connector

Conversation

@shadyvb

@shadyvb shadyvb commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes XWPENG-20.

Adds a bundled AI Client connector to Stream that listens to WordPress AI Client before/after_generate_result hooks and writes audit records for each generation. Records include acting user, timestamp, provider, model, input/output/thinking token counts, duration, finish reason, and extended metadata. Full prompt and response text capture is supported via a single opt-in setting (log_prompt_and_response_text), disabled by default with a PII warning. Developer filters wp_stream_ai_client_log_prompt and wp_stream_ai_client_log_response allow redaction or omission of stored text. The Stream list table shows only the first line of multiline summaries so token/metadata rows stay scannable when prompt/response logging is enabled.

Checklist

  • Project documentation has been updated to reflect the changes in this pull request, if applicable.
  • I have tested the changes in the local development environment (see contributing.md).
  • I have added phpunit tests.

Release Changelog

  • New: AI Client connector logs WordPress AI Client generations (tokens, model, provider, duration) with optional full prompt/response capture behind a single opt-in toggle.

Release Checklist

  • This pull request is to the develop branch.
  • Release version follows semantic versioning. Does it include breaking changes?
  • Update changelog in readme.txt.
  • Bump version in stream.php.
  • Bump Stable tag in readme.txt.
  • Bump version in classes/class-plugin.php.
  • Draft a release on GitHub.

Test plan

  • On WP 7.0+ with AI Client configured, trigger a generation and confirm a Stream record appears under AI Client → Prompts → Generated with user, model, provider, and token counts.
  • With Log Prompt and Response text off (default), confirm prompt/response body are not stored in the record summary or meta.
  • Enable Log Prompt and Response text, confirm the PII warning is visible, prompt/response appear in the record, and the list table shows only the first summary line.
  • Hook wp_stream_ai_client_log_prompt / wp_stream_ai_client_log_response to redact text; confirm stored values reflect the filter output.
  • On a site without WP_AI_Client_Event_Dispatcher, confirm Stream loads with no fatals and no AI records are written.
  • Run PHPUnit: vendor/bin/phpunit --filter Connector_AI_Client and vendor/bin/phpunit --filter Test_List_Table.

@shadyvb
shadyvb force-pushed the feature/add-ai-client-connector branch from 51dfd34 to 496a047 Compare August 21, 2026 11:54
Register a bundled Stream connector that listens to wp_ai_client_before/
after_generate_result and writes activity records with provider, model,
token counts (input/output/thought), duration, and extended metadata.

- Single opt-in toggle (log_prompt_and_response_text) for full prompt/
  response capture, disabled by default with PII warning
- wp_stream_ai_client_log_prompt / log_response filters for redaction
- List table first-line summary preview for multiline entries
- PHPUnit coverage for logging, toggles, filters, and graceful no-op
- Docs, changelog, connectors.md regen; gitignore .ai/ local tooling
@shadyvb
shadyvb force-pushed the feature/add-ai-client-connector branch from 496a047 to f4132b0 Compare August 21, 2026 11:54
@shadyvb
shadyvb marked this pull request as ready for review August 21, 2026 11:55

@bartoszgadomski bartoszgadomski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work @shadyvb! I left inline comments, please take a look.

Comment thread readme.txt Outdated
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php Outdated
Comment thread connectors/class-connector-ai-client.php
Comment thread classes/class-list-table.php Outdated
… and PII warnings match Stream's existing patterns.

Truncated summaries now show an ellipsis, log templates stay translatable without early escaping, and operators are warned that stored prompt text may be forwarded to alerts or webhooks.
…display.

The connector deliberately renders tokens as %4$d/%6$d/%5$d; align PHPUnit expectations with that summary format so CI passes.
Resolve changelog conflict by keeping [Unreleased] AI Client entries
above the 4.4.0 release notes from develop.

@bartoszgadomski bartoszgadomski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Follow-up notes after the review-response commits.

Comment thread readme.txt

When WordPress 7.0+ provides the AI Client event dispatcher (`WP_AI_Client_Event_Dispatcher`), Stream logs each AI generation as an activity record under **AI Client → Prompts → Generated**. If the dispatcher is not available, the connector registers no hooks and has no effect.

By default, Stream stores metadata for every generation: operation, provider, model, input/output/thought token counts, duration, finish reason, and other extended fields when present. The activity summary shows a one-line preview (for example, `chat via openai/gpt-4o (tokens: 120/0/45) in 842ms`). Multiline summaries display only the first line in the list table; open a record to see the full text.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leftover docs: this still describes the counts as input/output/thought, but the summary template (and the PHPUnit assertion) renders input/thought/output. The example 120/0/45 already matches that display order.

Please align the prose with the deliberate %4$d/%6$d/%5$d format, e.g. “input/thought/output token counts” and a short note that the three numbers in the preview are input, thought, then output.

Comment thread readme.txt

By default, Stream stores metadata for every generation: operation, provider, model, input/output/thought token counts, duration, finish reason, and other extended fields when present. The activity summary shows a one-line preview (for example, `chat via openai/gpt-4o (tokens: 120/0/45) in 842ms`). Multiline summaries display only the first line in the list table; open a record to see the full text.

Prompt and response text are **not** logged by default. To opt in, enable **Log Prompt and Response text** under **Stream → Settings → AI Client**. When enabled, prompt and response text are appended to the activity summary (not stored in meta, which is size-limited). **Privacy Warning:** This content may include personally identifiable information (PII). Ensure your privacy policy covers AI data collection before enabling.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leftover docs: the Settings checkbox warning now covers Slack/IFTTT (and the redaction filters), but this readme.txt PII paragraph still only talks about storage.

Please mirror the settings copy here so operators who never open Stream → Settings still see that prompt/response text may be forwarded to configured alerts or webhooks, and that wp_stream_ai_client_log_prompt / wp_stream_ai_client_log_response are the redaction point.

* Injects the AI Client settings section into Stream's settings fields array.
*
* Adds opt-in checkbox — log_prompt_and_response_text — under
* a dedicated "AI Client" section in Stream → Settings. Both default to off.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leftover docs: this still says “Both default to off”, but there is only one checkbox (log_prompt_and_response_text). Looks like a leftover from an earlier two-toggle design — please drop “Both”.

'<strong>%s</strong> %s %s',
esc_html__( 'Privacy Warning:', 'stream' ),
esc_html__( 'This content may include personally identifiable information (PII). Ensure your privacy policy covers AI data collection before enabling.', 'stream' ),
esc_html__( 'When enabled, prompt and response text are stored in the record summary and may be forwarded verbatim to any configured Stream alerts or webhooks (e.g. Slack, IFTTT). Use the wp_stream_ai_client_log_prompt and wp_stream_ai_client_log_response filters to redact or omit text before it is stored.', 'stream' )

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

“Verbatim” overstates what Stream actually persists.

With this setting on, prompt/response text is written into summary via log(), then DB::sanitize_record() runs wp_strip_all_tags() on every scalar field before insert (classes/class-db.php). Markup, List<T>-style generics, and anything that looks like an HTML tag is altered or removed, so the stored (and alert-forwarded) text is not a byte-for-byte copy of the generation.

That sanitizer is existing Stream behavior, not new in this PR — but this connector is the first to put user-authored bodies in summary, and this warning is the first to promise they are stored and forwarded verbatim.

Please either soften the wording (e.g. that HTML is stripped on insert) or document the limitation next to the opt-in. Same note belongs in readme.txt if you add the alerts sentence there.

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.

2 participants