This commit is contained in:
Your Name
2026-10-09 14:13:57 +08:00
parent 51d8fd409e
commit 5706e9a6a5
15 changed files with 732 additions and 162 deletions
@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace app\common\service {
function config(string $name): array
{
return $GLOBALS['ancientReuseConfig'];
}
function curl_init(): \stdClass
{
return new \stdClass();
}
function curl_setopt_array(\stdClass $handle, array $options): bool
{
$handle->options = $options;
$GLOBALS['ancientReuseRequests'][] = json_decode($options[CURLOPT_POSTFIELDS], true);
return true;
}
function curl_exec(\stdClass $handle): string
{
$options = $handle->options;
if (isset($options[CURLOPT_WRITEFUNCTION])) {
$options[CURLOPT_HEADERFUNCTION]($handle, "HTTP/1.1 200 OK\r\n");
$options[CURLOPT_WRITEFUNCTION]($handle,
"data: {\"event\":\"message\",\"answer\":\"offline\"}\n\n"
. "data: {\"event\":\"message_end\"}\n\n");
return '';
}
return '{"answer":"offline"}';
}
function curl_errno(\stdClass $handle): int { return 0; }
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\ClinicalKnowledgeReference;
use app\common\service\DifyChatService;
use app\common\service\TcmAncientBooksReference;
function ancientReuseExpect(bool $condition, string $message): void
{
if (!$condition) {
fwrite(STDERR, "FAIL: {$message}\n");
exit(1);
}
}
$indexProperty = new ReflectionProperty(TcmAncientBooksReference::class, 'index');
$indexProperty->setValue(null, [
'commit' => TcmAncientBooksReference::COMMIT,
'index_version' => TcmAncientBooksReference::INDEX_VERSION,
'terms' => [
'消渴' => [[
'title' => '甲书', 'chapter' => '消渴篇', 'path' => '甲书.txt',
'line' => 42, 'excerpt' => '消渴原文。', 'score' => 15,
]],
],
'chapter_terms' => [
'痛风' => [[
'title' => '乙书', 'chapter' => '痛风篇', 'path' => '乙书.txt',
'line' => 88, 'excerpt' => '痛风原文。', 'score' => 12,
]],
],
]);
$ancientReuseConfig = [
'enable' => true, 'base_url' => 'https://ai.example.test/v1/chat-messages',
'timeout' => 30, 'models' => ['qwen' => ['name' => 'offline', 'api_key' => 'test-key']],
];
foreach (['患者糖尿病,请分析。', '患者痛风,请分析。', '患者有未收录的症状。'] as $case) {
$expectedSources = ClinicalKnowledgeReference::ancientBookSources($case);
$expectedPrompt = ClinicalKnowledgeReference::augmentQuery($case);
foreach (['blocking', 'streaming'] as $mode) {
$ancientReuseRequests = [];
if ($mode === 'blocking') {
$result = DifyChatService::chat('qwen', [], $case, 'offline-user');
} else {
$deltas = [];
$result = DifyChatService::streamChat('qwen', [], $case, 'offline-user',
static function (string $delta) use (&$deltas): void { $deltas[] = $delta; });
ancientReuseExpect($deltas === ['offline'], 'streaming forwards the upstream delta');
}
ancientReuseExpect($result['ok'] === true, "$mode request succeeds");
ancientReuseExpect(count($ancientReuseRequests) === 1, "$mode sends one request");
ancientReuseExpect($ancientReuseRequests[0]['query'] === $expectedPrompt,
"$mode prompt remains byte-for-byte identical");
ancientReuseExpect($result['ancient_book_sources'] === $expectedSources,
"$mode returns exactly the selected citations");
}
}
$indexProperty->setValue(null, null);
echo "Dify ancient-books reuse contract passed.\n";
}