更新
This commit is contained in:
@@ -1350,6 +1350,8 @@ class DifyChatService
|
||||
|
||||
$buffer = '';
|
||||
$state = self::newStreamState();
|
||||
$upstreamTiming = is_callable($options['on_upstream_timing'] ?? null) ? new DifyStreamTiming() : null;
|
||||
$state['timing'] = $upstreamTiming;
|
||||
$state['on_task'] = $options['on_task'] ?? null;
|
||||
$state['on_terminal'] = $options['on_terminal'] ?? null;
|
||||
$notify = self::transferProgressNotifier($options);
|
||||
@@ -1416,9 +1418,10 @@ class DifyChatService
|
||||
$responseCode = 0;
|
||||
$errorBody = '';
|
||||
$errorBodyOverflow = false;
|
||||
$header = static function ($handle, string $line) use (&$responseCode, &$errorBody, &$errorBodyOverflow, $markSubmitted): int {
|
||||
$header = static function ($handle, string $line) use (&$responseCode, &$errorBody, &$errorBodyOverflow, $markSubmitted, $upstreamTiming): int {
|
||||
if (preg_match('/^HTTP\/\S+\s+(\d{3})(?:\s|$)/i', trim($line), $matches) === 1) {
|
||||
$responseCode = (int) $matches[1];
|
||||
$upstreamTiming?->headers($responseCode);
|
||||
$errorBody = '';
|
||||
$errorBodyOverflow = false;
|
||||
if ($responseCode >= 200 && $responseCode < 300) $markSubmitted();
|
||||
@@ -1432,9 +1435,11 @@ class DifyChatService
|
||||
&$responseCode,
|
||||
&$errorBody,
|
||||
&$errorBodyOverflow,
|
||||
$upstreamTiming,
|
||||
$forward,
|
||||
$abort
|
||||
): int {
|
||||
$upstreamTiming?->body(strlen($chunk));
|
||||
if ($responseCode < 200 || $responseCode >= 300) {
|
||||
// Keep a bounded JSON error only until its safe code/reason has
|
||||
// been extracted. Never feed HTTP error bodies to the SSE parser.
|
||||
@@ -1499,6 +1504,15 @@ class DifyChatService
|
||||
// A callback failure may escape libcurl before the regular cancel
|
||||
// poll. Make the coordinated stop attempt before closing this handle.
|
||||
try { $abort(); } catch (\Throwable $ignored) {}
|
||||
if ($upstreamTiming !== null) {
|
||||
try {
|
||||
$upstreamTiming->transport(['connect_ms' => curl_getinfo($ch, CURLINFO_CONNECT_TIME) * 1000,
|
||||
'tls_ms' => curl_getinfo($ch, CURLINFO_APPCONNECT_TIME) * 1000,
|
||||
'header_ttfb_ms' => curl_getinfo($ch, CURLINFO_STARTTRANSFER_TIME) * 1000,
|
||||
'transfer_ms' => curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000,
|
||||
'http_status' => $httpCode, 'curl_errno' => $errno]);
|
||||
} catch (\Throwable $ignored) {}
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
@@ -1522,6 +1536,9 @@ class DifyChatService
|
||||
$state['upstream_reason'] = $metadata['upstream_reason'];
|
||||
}
|
||||
unset($errorBody);
|
||||
if ($upstreamTiming !== null) {
|
||||
try { ($options['on_upstream_timing'])($upstreamTiming); } catch (\Throwable $ignored) {}
|
||||
}
|
||||
|
||||
return [
|
||||
'errno' => $errno,
|
||||
@@ -1686,6 +1703,7 @@ class DifyChatService
|
||||
}
|
||||
}
|
||||
$event = strtolower((string) ($decoded['event'] ?? ''));
|
||||
if (($state['timing'] ?? null) instanceof DifyStreamTiming) $state['timing']->frame($decoded, $protocol);
|
||||
if ($event === 'workflow_finished') {
|
||||
$rawStatus = $decoded['data']['status'] ?? '';
|
||||
$status = is_string($rawStatus) ? strtolower($rawStatus) : '';
|
||||
@@ -1720,6 +1738,7 @@ class DifyChatService
|
||||
$state['message_id'] = (string) ($decoded['message_id'] ?? $state['message_id']);
|
||||
} else {
|
||||
if ($state['finished'] || $state['upstream_error']) return;
|
||||
if (($state['timing'] ?? null) instanceof DifyStreamTiming) $state['timing']->frame($decoded, $protocol);
|
||||
if (is_array($decoded['error'] ?? null)) {
|
||||
$state['upstream_error'] = true;
|
||||
$metadata = self::upstreamErrorMetadata($decoded);
|
||||
@@ -1745,6 +1764,7 @@ class DifyChatService
|
||||
return;
|
||||
}
|
||||
if ($state['discard_deltas']) return;
|
||||
if (($state['timing'] ?? null) instanceof DifyStreamTiming) $state['timing']->delivered();
|
||||
$state['content'] .= $delta;
|
||||
$state['emitted'] = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user