PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.4
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.4
4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 All 202 releases
← All changes | includes/Utils/AIUsage.php +64 -1 4.6.1 → 4.9.4 View file →
@@ -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,58 @@
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,attachment:int,recording:int}
153 + */
154 + protected static function write_with_ai_modes( $actions ) {
155 + $modes = [ 'prompt' => 0, 'source' => 0, 'git' => 0, 'attachment' => 0, 'recording' => 0 ];
156 +
157 + // Anything unrecognised lands in `prompt`, which is why `attachment` and
158 + // `recording` need explicit arms: without them every file-based
159 + // generation was reported as a plain prompt, making the attachment tab
160 + // look unused in the insights snapshot.
161 + foreach ( (array) $actions as $action => $count ) {
162 + $count = (int) $count;
163 + if ( 'from-source' === $action ) {
164 + $modes['source'] += $count;
165 + } elseif ( 'from-git' === $action ) {
166 + $modes['git'] += $count;
167 + } elseif ( 'from-attachment' === $action ) {
168 + $modes['attachment'] += $count;
169 + } elseif ( 'from-recording' === $action || 'transcribe-attachment' === $action ) {
170 + // `from-recording` is the generation. `transcribe-attachment` is
171 + // only kept so counts recorded before that split still land here.
172 + $modes['recording'] += $count;
173 + } else {
174 + $modes['prompt'] += $count;
175 + }
176 + }
177 +
178 + return $modes;
116 179 }
117 180 }