Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions src/Agents/Adapters/Perplexity.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function __construct(
*/
public function isSchemaSupported(): bool
{
return false;
return true;
}

/**
Expand Down Expand Up @@ -128,7 +128,7 @@ protected function process(Chunk $chunk, ?callable $listener): string
stripos($trimmed, '<html') === 0 ||
stripos($trimmed, '<!DOCTYPE html') === 0
) {
return PHP_EOL.$data;
return $this->sanitizeHtmlError($data);
}

foreach ($lines as $line) {
Expand Down Expand Up @@ -162,4 +162,45 @@ protected function process(Chunk $chunk, ?callable $listener): string

return $block;
}

/**
* Sanitize HTML error responses into readable error messages
*
* @param string $html
* @return string
*/
protected function sanitizeHtmlError(string $html): string
{
// Try to extract the error from the title tag
if (preg_match('/<title>(.*?)<\/title>/is', $html, $matches)) {
$errorMessage = trim($matches[1]);

// Extract status code and message if present (e.g., "401 Authorization Required")
if (preg_match('/^(\d{3})\s+(.+)$/i', $errorMessage, $parts)) {
$statusCode = $parts[1];
$message = $parts[2];

return '(http_'.$statusCode.') '.$message;
}

return '(html_error) '.$errorMessage;
}

// Try to extract from h1 tag
if (preg_match('/<h1>(.*?)<\/h1>/is', $html, $matches)) {
$errorMessage = trim(strip_tags($matches[1]));

if (preg_match('/^(\d{3})\s+(.+)$/i', $errorMessage, $parts)) {
$statusCode = $parts[1];
$message = $parts[2];

return '(http_'.$statusCode.') '.$message;
}

return '(html_error) '.$errorMessage;
}

// Fallback for unrecognized HTML errors
return '(html_error) Received HTML error response from API';
}
}