修复
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use app\adminapi\service\AssistantRequestControl as Control;
|
||||
use app\common\service\DifyChatService as Stream;
|
||||
|
||||
// Direct production parser + private synthetic controls. No config/socket/model/DB.
|
||||
$directory = dirname(__DIR__, 2) . '/app/artifacts/ai_concurrency/.r23-integration-' . bin2hex(random_bytes(6));
|
||||
if (!mkdir($directory, 0700)) throw new RuntimeException('Synthetic directory unavailable');
|
||||
$results = [];
|
||||
$make = static function (int $number) use ($directory): array {
|
||||
$id = sprintf('19345678-1234-4234-8234-%012d', $number);
|
||||
$control = new Control(71, 3111, $id, $directory);
|
||||
if (!$control->begin()) throw new RuntimeException('Synthetic begin failed');
|
||||
$path = $directory . '/' . hash('sha256', '71:3111:' . $id) . '.json';
|
||||
return [$control, $path];
|
||||
};
|
||||
$stateFor = static function (Control $control): array {
|
||||
$state = (new ReflectionMethod(Stream::class, 'newStreamState'))->invoke(null);
|
||||
$state['on_task'] = static fn (string $task, string $run = '') => $control->bindTask('qwen', 'synthetic-user', $task, $run);
|
||||
$state['on_terminal'] = static fn (string $task, string $status, string $run = '') => $control->markTerminal($task, $status, $run);
|
||||
return $state;
|
||||
};
|
||||
$frame = static function (array &$state, array $data): void {
|
||||
$args = ['dify', 'data: ' . json_encode($data, JSON_THROW_ON_ERROR), &$state, static fn (string $text): bool => true];
|
||||
(new ReflectionMethod(Stream::class, 'consumeStreamFrame'))->invokeArgs(null, $args);
|
||||
};
|
||||
$read = static fn (string $path): array => json_decode((string) file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
|
||||
try {
|
||||
[$control, $path] = $make(1);
|
||||
$state = $stateFor($control);
|
||||
$frame($state, ['event'=>'workflow_started','task_id'=>'synthetic-task','workflow_run_id'=>'synthetic-run','data'=>['id'=>'synthetic-run']]);
|
||||
$results['normal_original_pair_persisted'] = ($read($path)['upstream']['workflow_run_id'] ?? '') === 'synthetic-run';
|
||||
$frame($state, ['event'=>'workflow_finished','task_id'=>'synthetic-task','workflow_run_id'=>'synthetic-run','data'=>['id'=>'synthetic-run','status'=>'succeeded']]);
|
||||
$control->finish('done');
|
||||
$results['normal_exact_pair_terminal'] = $state['upstream_terminal_confirmed'] && $control->publicState()['upstream_pending_task_count'] === 0;
|
||||
|
||||
[$control, $path] = $make(2);
|
||||
$control->bindTask('qwen', 'synthetic-user', 'original-task', 'original-run');
|
||||
$state = $stateFor($control);
|
||||
$frame($state, ['event'=>'workflow_started','task_id'=>'unexpected-created-task','workflow_run_id'=>'unexpected-created-run','data'=>['id'=>'unexpected-created-run']]);
|
||||
$record = $read($path);
|
||||
$results['handoff_fails_closed'] = $state['callback_error'] && ($record['upstream']['workflow_run_id'] ?? '') === 'original-run';
|
||||
$results['handoff_original_start_run_retained'] = ($record['handoff_cleanup']['unexpected-created-task']['upstream']['workflow_run_id'] ?? '') === 'unexpected-created-run';
|
||||
$control->finish('error');
|
||||
$results['handoff_pending_count_preserved'] = $control->publicState()['upstream_pending_task_count'] === 2;
|
||||
|
||||
foreach (["newline-run\n", "space-run ", "run\r\n"] as $number => $bad) {
|
||||
[$control, $path] = $make(10 + $number);
|
||||
$rejected = false;
|
||||
try { $control->bindTask('qwen', 'synthetic-user', 'synthetic-task', $bad); }
|
||||
catch (RuntimeException $ignored) { $rejected = true; }
|
||||
$results['strict_control_run_' . $number] = $rejected;
|
||||
}
|
||||
echo json_encode(['scope'=>'pure parser/control integration','checks'=>$results,'all_passed'=>!in_array(false,$results,true)], JSON_THROW_ON_ERROR), "\n";
|
||||
$exitCode = in_array('--observe', $argv, true) || !in_array(false,$results,true) ? 0 : 1;
|
||||
} finally {
|
||||
$real = realpath($directory);
|
||||
$base = realpath(dirname(__DIR__, 2) . '/app/artifacts/ai_concurrency');
|
||||
if ($real === false || $base === false || !str_starts_with(str_replace('\\','/',$real), str_replace('\\','/',$base) . '/')) throw new RuntimeException('Synthetic cleanup boundary');
|
||||
foreach (new DirectoryIterator($real) as $file) if ($file->isFile() && !$file->isLink()) unlink($file->getPathname());
|
||||
rmdir($real);
|
||||
}
|
||||
exit($exitCode);
|
||||
Reference in New Issue
Block a user