$yesterday, 'date_to' => $today, 'per_page' => 100, ) ); if ( empty( $events ) ) { return; } $subject = sprintf( '%s - Activity Log Summary (%s)', get_bloginfo( 'name' ), $today ); // AI-native analysis (#4): locally-computed anomaly flags always, // the WordPress AI Client summary when explicitly enabled and available // (BYOK), a deterministic overview sentence otherwise. $flags = \ActivityLog404\AiSummary::flag_anomalies( $events ); $summary = \ActivityLog404\AiSummary::summarize( $events, $flags ); $overview = \ActivityLog404\AiSummary::local_overview( $events ); $html = '
' . esc_html__( 'What happened and why it matters', '404ops-activity-log' ) . '
'; if ( null !== $summary ) { $html .= '' . esc_html( $summary['text'] ) . '
'; } $html .= '' . esc_html( $overview ) . '
'; foreach ( $flags as $flag ) { $color = 'critical' === $flag['level'] ? '#d63638' : '#dba617'; $html .= '[!] ' . esc_html( $flag['text'] ) . '
'; } $html .= 'Here\'s a summary of site activities:
'; $html .= '| Time | '; $html .= 'User | '; $html .= 'Event | '; $html .= 'Summary | '; $html .= '
|---|---|---|---|
| ' . esc_html( $time ) . ' | '; $html .= '' . esc_html( $user ) . ' | '; $html .= '' . esc_html( $event_label ) . ' | '; $html .= '' . esc_html( (string) $event['summary'] ) . ' | '; $html .= '