fix: tolerate markdown-fenced JSON from LLM responses (v0.4.3)

Models like GPT 5.1 Nano ignore response_format: json_object and wrap
their JSON in ```json fences or add preamble text. New Json_Extractor
utility tries: (1) direct decode, (2) strip markdown fences, (3) find
outermost { ... } substring. Applied to analyzer and chief editor
parsers. Raw response logged on parse failure for debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
peptiderepo
2026-04-19 15:40:37 +07:00
parent 3e1e5efe09
commit 65560ea0b5
5 changed files with 78 additions and 4 deletions

View File

@@ -15,6 +15,7 @@ declare(strict_types=1);
* @see core/class-analysis-prompts.php — System/user prompt builders + performance context.
* @see providers/interface-llm-provider.php — LLM used for analysis.
* @see core/class-cost-tracker.php — Logs API costs.
* @see core/class-json-extractor.php — Tolerant JSON parsing for LLM output.
* @see core/class-idea-scorer.php — Consumes analysis results.
* @see ARCHITECTURE.md — Data flow step 2.
*/
@@ -175,9 +176,10 @@ class PRAutoBlogger_Content_Analyzer {
* @return PRAutoBlogger_Analysis_Result[]
*/
private function parse_analysis_response( string $content, array $source_items ): array {
$data = json_decode( $content, true );
$data = PRAutoBlogger_Json_Extractor::decode( $content );
if ( ! isset( $data['patterns'] ) || ! is_array( $data['patterns'] ) ) {
PRAutoBlogger_Logger::instance()->error( 'Analysis response was not valid JSON or missing patterns key.', 'analyzer' );
PRAutoBlogger_Logger::instance()->debug( 'Raw analysis response: ' . mb_substr( $content, 0, 500 ), 'analyzer' );
return [];
}