81 lines
2.8 KiB
PHP
81 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\service {
|
|
function config(string $name): array
|
|
{
|
|
return $GLOBALS['clinicalChatConfig'];
|
|
}
|
|
|
|
function curl_init(): \stdClass
|
|
{
|
|
return new \stdClass();
|
|
}
|
|
|
|
function curl_setopt(\stdClass $handle, int $option, mixed $value): bool
|
|
{
|
|
$handle->options[$option] = $value;
|
|
return true;
|
|
}
|
|
|
|
function curl_exec(\stdClass $handle): string|bool
|
|
{
|
|
$GLOBALS['clinicalChatPayloads'][] = json_decode($handle->options[CURLOPT_POSTFIELDS], true);
|
|
if (isset($handle->options[CURLOPT_WRITEFUNCTION])) {
|
|
$write = $handle->options[CURLOPT_WRITEFUNCTION];
|
|
$write($handle, "data: {\"choices\":[{\"delta\":{\"content\":\"offline stream\"}}]}\n\n");
|
|
return true;
|
|
}
|
|
return '{"choices":[{"message":{"content":"offline reply"}}]}';
|
|
}
|
|
|
|
function curl_errno(\stdClass $handle): int { return 0; }
|
|
function curl_error(\stdClass $handle): string { return ''; }
|
|
function curl_getinfo(\stdClass $handle, int $option): int { return 200; }
|
|
function curl_close(\stdClass $handle): void {}
|
|
}
|
|
|
|
namespace {
|
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
|
|
|
use app\common\service\AiChatService;
|
|
use app\common\service\NihaixiaClinicalSkill;
|
|
|
|
function chatSkillExpect(bool $condition, string $message): void
|
|
{
|
|
if (!$condition) {
|
|
fwrite(STDERR, "FAIL: {$message}\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
$clinicalChatConfig = [
|
|
'enable' => true,
|
|
'api_key' => 'offline-fixture',
|
|
'base_url' => 'https://ai.example.test',
|
|
'model' => 'offline-model',
|
|
];
|
|
$clinicalChatPayloads = [];
|
|
$messages = [
|
|
['role' => 'system', 'content' => '只输出 JSON'],
|
|
['role' => 'user', 'content' => '分析该患者症状'],
|
|
];
|
|
|
|
$blocking = AiChatService::chat($messages);
|
|
chatSkillExpect($blocking['ok'] === true, 'blocking chat succeeds offline');
|
|
$deltas = [];
|
|
$streaming = AiChatService::streamChat($messages, static function (string $delta) use (&$deltas): void {
|
|
$deltas[] = $delta;
|
|
});
|
|
chatSkillExpect($streaming['ok'] === true && $deltas === ['offline stream'], 'streaming chat succeeds offline');
|
|
chatSkillExpect(count($clinicalChatPayloads) === 2, 'both transports sent one request');
|
|
foreach ($clinicalChatPayloads as $payload) {
|
|
$wireMessages = $payload['messages'];
|
|
chatSkillExpect(str_contains($wireMessages[0]['content'], NihaixiaClinicalSkill::VERSION), 'wire request includes the clinical skill');
|
|
chatSkillExpect($wireMessages[1] === $messages[0] && $wireMessages[2] === $messages[1], 'original format and patient question are preserved');
|
|
}
|
|
|
|
echo "AiChat clinical skill transport contract passed.\n";
|
|
}
|