This commit is contained in:
Your Name
2026-10-27 14:03:35 +08:00
parent 7986e4baf5
commit f9cbd42113
417 changed files with 71876 additions and 5344 deletions
@@ -32,6 +32,7 @@ namespace app\common\service {
$GLOBALS['classificationRequests'][] = [
'mode' => $streaming ? 'streaming' : 'blocking', 'payload' => $payload,
'raw' => $options[CURLOPT_POSTFIELDS], 'timeout' => $options[CURLOPT_TIMEOUT],
'timeout_ms' => $options[CURLOPT_TIMEOUT_MS] ?? $options[CURLOPT_TIMEOUT] * 1000,
];
$fixture = array_shift($GLOBALS['classificationFixtures']);
if (!is_array($fixture)) throw new \RuntimeException('Unexpected extra upstream request');
@@ -75,9 +76,12 @@ namespace app\common\service {
namespace {
$root = dirname(__DIR__, 2);
require $root . '/server/app/common/logic/BaseLogic.php';
require_once $root . '/server/app/common/service/DifyReasoningTextFilter.php';
require $root . '/server/app/common/service/DifyChatService.php';
require $root . '/server/app/common/service/DifyStreamTiming.php';
require $root . '/server/app/adminapi/service/AssistantSseTiming.php';
require $root . '/server/app/adminapi/service/TcmClinicalFactStateGuard.php';
require $root . '/server/app/adminapi/service/TcmClinicalReportStream.php';
require $root . '/server/app/adminapi/logic/tcm/DiagnosisAiLogic.php';
use app\common\service\DifyChatService;
use app\adminapi\logic\tcm\DiagnosisAiLogic;
@@ -187,13 +191,20 @@ namespace {
&& count($classificationRequests[1]['payload']['files']) === 2
&& $classificationRequests[0]['payload']['files'] === $classificationRequests[1]['payload']['files']
&& $classificationRequests[0]['payload']['inputs'] === $classificationRequests[1]['payload']['inputs']
&& $classificationRequests[1]['timeout'] <= 4, 'Actual assistant recovers response_mode with both files and the remaining shared budget');
&& $classificationRequests[1]['timeout_ms'] < 5000
&& $classificationRequests[1]['timeout_ms'] <= $classificationRequests[0]['timeout_ms'],
'Actual assistant recovers response_mode with both files and the remaining precise shared budget');
// An emitted clinical delta prevents replay even if a later SSE error names inputs.
$reset([['http' => 200, 'body' => "data: {\"event\":\"message\",\"answer\":\"synthetic partial\"}\n\ndata: {\"event\":\"error\",\"code\":\"invalid_inputs\"}\n\n"]]);
$answer = DiagnosisAiLogic::streamPreparedAssistant($prepared, static fn (): bool => true, null,
$reset([['http' => 200, 'body' => "data: {\"event\":\"message\",\"answer\":\"synthetic partial\\n\\n\"}\n\ndata: {\"event\":\"error\",\"code\":\"invalid_inputs\"}\n\n"]]);
$classificationVisible = '';
$answer = DiagnosisAiLogic::streamPreparedAssistant($prepared, static function (string $text) use (&$classificationVisible): bool {
$classificationVisible .= $text;
return true;
}, null,
new AssistantSseTiming(), ['knowledge_mode' => 'evidence']);
classificationExpect($answer === null && count($classificationRequests) === 1, 'No inputs or blocking replay after delivered text');
classificationExpect($answer === null && count($classificationRequests) === 1
&& $classificationVisible === "synthetic partial\n\n", 'No inputs or blocking replay after a validated paragraph actually reached the client');
$reset([['http' => 400, 'cancel' => true, 'error' => ['code' => 'file_too_large']]]);
$result = DifyChatService::chat('qwen', [], 'synthetic query', 'synthetic-user', $files,