| @@ -47,8 +47,11 @@ | ||
| 47 | 47 | 'article_summary', |
| 48 | 48 | 'quality_score', |
| 49 | 49 | 'glossaries_write_with_ai', |
| 50 | 50 | 'faq_write_with_ai', |
| 51 | + 'sample_docs', | |
| 52 | + 'ai_suggest_terms', | |
| 53 | + 'api_docs_ai', | |
| 51 | 54 | ]; |
| 52 | 55 | |
| 53 | 56 | /** |
| 54 | 57 | * Record one successful AI invocation. |
| @@ -94,10 +97,19 @@ | ||
| 94 | 97 | } |
| 95 | 98 | |
| 96 | 99 | /** |
| 97 | 100 | * Normalised, fixed-schema snapshot for the wpinsight collector. Every feature key |
| 98 | - * is always present (default 0); the AI Edit action breakdown is included when set. | |
| 101 | + * is always present (default 0); action sub-maps are included when set. | |
| 99 | 102 | * |
| 103 | + * Sub-map handling: | |
| 104 | + * - `ai_edit_actions` — shipped as-is (improve/rewrite/shorten/…). | |
| 105 | + * - `write_with_ai_modes` — the raw `write_with_ai_actions` map is rolled up into | |
| 106 | + * the three user-facing source modes (prompt / source / git) so wpinsight reads a | |
| 107 | + * stable, human-meaningful breakdown regardless of internal action names. Always | |
| 108 | + * present so the schema is stable. | |
| 109 | + * - `sample_docs_actions` — per content-type (docs/faq/product_faq), when set. | |
| 110 | + * - `ai_suggest_terms_actions`— per taxonomy (doc_category/doc_tag/glossaries), when set. | |
| 111 | + * | |
| 100 | 112 | * @return array<string,int|array<string,int>> |
| 101 | 113 | */ |
| 102 | 114 | public static function snapshot() { |
| 103 | 115 | $usage = get_option( self::OPTION_KEY, [] ); |
| @@ -111,7 +123,48 @@ | ||
| 111 | 123 | if ( ! empty( $usage['ai_edit_actions'] ) && is_array( $usage['ai_edit_actions'] ) ) { |
| 112 | 124 | $out['ai_edit_actions'] = array_map( 'intval', $usage['ai_edit_actions'] ); |
| 113 | 125 | } |
| 114 | 126 | |
| 127 | + // Roll the raw Write-with-AI actions up into the three source modes the user picks. | |
| 128 | + $out['write_with_ai_modes'] = self::write_with_ai_modes( $usage['write_with_ai_actions'] ?? [] ); | |
| 129 | + | |
| 130 | + if ( ! empty( $usage['sample_docs_actions'] ) && is_array( $usage['sample_docs_actions'] ) ) { | |
| 131 | + $out['sample_docs_actions'] = array_map( 'intval', $usage['sample_docs_actions'] ); | |
| 132 | + } | |
| 133 | + | |
| 134 | + if ( ! empty( $usage['ai_suggest_terms_actions'] ) && is_array( $usage['ai_suggest_terms_actions'] ) ) { | |
| 135 | + $out['ai_suggest_terms_actions'] = array_map( 'intval', $usage['ai_suggest_terms_actions'] ); | |
| 136 | + } | |
| 137 | + | |
| 115 | 138 | return $out; |
| 139 | + } | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Normalise the raw `write_with_ai_actions` sub-map (keyed by internal action names | |
| 143 | + * from the Write-with-AI REST endpoint) into the three source modes surfaced in the | |
| 144 | + * AI Studio "Write Documentation" modal: Prompt | From Source | From Git. | |
| 145 | + * | |
| 146 | + * - `from-source` → source | |
| 147 | + * - `from-git` → git | |
| 148 | + * - generate-doc / generate-outline / expand-outline (and any future prompt-driven | |
| 149 | + * action) → prompt | |
| 150 | + * | |
| 151 | + * @param array<string,int> $actions | |
| 152 | + * @return array{prompt:int,source:int,git:int} | |
| 153 | + */ | |
| 154 | + protected static function write_with_ai_modes( $actions ) { | |
| 155 | + $modes = [ 'prompt' => 0, 'source' => 0, 'git' => 0 ]; | |
| 156 | + | |
| 157 | + foreach ( (array) $actions as $action => $count ) { | |
| 158 | + $count = (int) $count; | |
| 159 | + if ( 'from-source' === $action ) { | |
| 160 | + $modes['source'] += $count; | |
| 161 | + } elseif ( 'from-git' === $action ) { | |
| 162 | + $modes['git'] += $count; | |
| 163 | + } else { | |
| 164 | + $modes['prompt'] += $count; | |
| 165 | + } | |
| 166 | + } | |
| 167 | + | |
| 168 | + return $modes; | |
| 116 | 169 | } |
| 117 | 170 | } |