fix: handle null content in OpenRouter response parser
Some models (and the openrouter/free router) may return null content instead of a string. The old check used isset() which returns false for null, triggering the "unexpected response format" error. Now: checks for choices[0].message (not content), treats null content as empty string, and logs the actual response shape on failure so we can diagnose what the model returned. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -50,16 +50,37 @@ class PRAutoBlogger_OpenRouter_Response_Parser {
|
|||||||
* @throws \RuntimeException If response structure is invalid.
|
* @throws \RuntimeException If response structure is invalid.
|
||||||
*/
|
*/
|
||||||
public function parse_success( array $data, string $model ): array {
|
public function parse_success( array $data, string $model ): array {
|
||||||
if ( ! isset( $data['choices'][0]['message']['content'] ) ) {
|
// Validate we have a choices array with at least one message.
|
||||||
throw new \RuntimeException(
|
if ( ! isset( $data['choices'][0]['message'] ) ) {
|
||||||
__( 'OpenRouter returned unexpected response format.', 'prautoblogger' )
|
// Log the raw shape so we can diagnose what the model actually returned.
|
||||||
|
PRAutoBlogger_Logger::instance()->error(
|
||||||
|
sprintf(
|
||||||
|
'Unexpected response shape from %s: %s',
|
||||||
|
$data['model'] ?? $model,
|
||||||
|
substr( (string) wp_json_encode( $data ), 0, 500 )
|
||||||
|
),
|
||||||
|
'openrouter'
|
||||||
);
|
);
|
||||||
|
throw new \RuntimeException(
|
||||||
|
sprintf(
|
||||||
|
/* translators: %s: model name */
|
||||||
|
__( 'OpenRouter model %s returned unexpected response format.', 'prautoblogger' ),
|
||||||
|
$data['model'] ?? $model
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content can be null (some models use tool_calls or refusal instead).
|
||||||
|
// Treat null as empty string — downstream callers handle empty content.
|
||||||
|
$content = $data['choices'][0]['message']['content'] ?? '';
|
||||||
|
if ( null === $content ) {
|
||||||
|
$content = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$usage = $data['usage'] ?? [];
|
$usage = $data['usage'] ?? [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'content' => $data['choices'][0]['message']['content'],
|
'content' => (string) $content,
|
||||||
'model' => $data['model'] ?? $model,
|
'model' => $data['model'] ?? $model,
|
||||||
'prompt_tokens' => (int) ( $usage['prompt_tokens'] ?? 0 ),
|
'prompt_tokens' => (int) ( $usage['prompt_tokens'] ?? 0 ),
|
||||||
'completion_tokens' => (int) ( $usage['completion_tokens'] ?? 0 ),
|
'completion_tokens' => (int) ( $usage['completion_tokens'] ?? 0 ),
|
||||||
|
|||||||
Reference in New Issue
Block a user