ai_agents_test-1.0.0-alpha1/src/Controller/AgentTestGroupController.php
src/Controller/AgentTestGroupController.php
<?php
namespace Drupal\ai_agents_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\ai_agents_test\Service\TestRunner;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Yaml\Yaml;
/**
* Controller for running tests.
*/
class AgentTestGroupController extends ControllerBase {
/**
* Constructs a new AgentTestController object.
*/
public function __construct(
protected TestRunner $testRunner,
protected RequestStack $requestStack,
) {
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('ai_agents_test.test_runner'),
$container->get('request_stack')
);
}
/**
* The test runner base page.
*/
public function testGroupPage($group_id) {
// Check if provider and model IDs are provided in the query string.
$query = $this->requestStack->getCurrentRequest()->query;
$provider_id = $query->get('provider_id');
$model_id = $query->get('model_id');
$eval_provider_id = $query->get('eval_provider_id');
$eval_model_id = $query->get('eval_model_id');
// Load the test group entity.
$test_group = $this->entityTypeManager()->getStorage('ai_agents_test_group')->load($group_id);
if (!$test_group) {
throw new \InvalidArgumentException(sprintf('Test with ID %d not found.', $group_id));
}
// Render a table with all the tests in the group.
$header = [
$this->t('Test Name'),
$this->t('Test Description'),
$this->t('Triggering Instruction'),
$this->t('Status'),
$this->t('Details'),
];
// Create a test group result entity.
/** @var \Drupal\ai_agents_test\Entity\AgentTestGroupResultInterface $test_group_result */
$test_group_result = $this->entityTypeManager()->getStorage('ai_agents_test_group_result')->create([
'label' => $test_group->label(),
'owner' => $this->currentUser()->id(),
]);
if ($provider_id) {
$test_group_result->set('chat_provider', $provider_id);
}
if ($model_id) {
$test_group_result->set('model', $model_id);
}
// Store evaluation model parameters.
if ($eval_provider_id) {
$test_group_result->set('eval_provider', $eval_provider_id);
}
if ($eval_model_id) {
$test_group_result->set('eval_model', $eval_model_id);
}
$test_group_result->set('process_status', 'running');
$test_group_result->set('ai_agents_test_group', $test_group->id());
$test_group_result->save();
$rows = [];
$tests_to_start = [];
foreach ($test_group->tests as $test_wrapper) {
$test = $test_wrapper->entity;
$rows[] = [
'data' => [
$test->label(),
$test->description->value,
$test->triggering_instructions->value,
[
'data' => $this->t('Run Test'),
'class' => [
'test-run-button',
'test-run-button-' . $test->id(),
],
'attributes' => [
'data-test-id' => $test->id(),
'data-group-id' => $test_group->id(),
],
],
[
'data' => 'not started',
'class' => [
'test-status-' . $test->id(),
],
],
[
'data' => 'no details',
'class' => [
'test-details-' . $test->id(),
],
],
],
'class' => [
'test-' . $test->id(),
],
];
$tests_to_start[] = $test->id();
}
return [
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#title' => $this->t('Test Group: @name', ['@name' => $test_group->label()]),
'#attributes' => [
'class' => [
'ai-agents-test-group',
],
],
'#attached' => [
'library' => [
'ai_agents_test/group_runner',
],
'drupalSettings' => [
'agentTestGroup' => [
'testGroupResultId' => $test_group_result->id(),
'testsToStart' => $tests_to_start,
'modelId' => $model_id,
'providerId' => $provider_id,
'evalProviderId' => $eval_provider_id,
'evalModelId' => $eval_model_id,
],
],
],
];
}
/**
* Ajax to trigger one test.
*/
public function ajaxTest($test_id, $group_id) {
// Check if provider and model IDs are provided in the query string.
$query = $this->requestStack->getCurrentRequest()->query;
$provider_id = $query->get('provider_id');
$model_id = $query->get('model_id');
$eval_provider_id = $query->get('eval_provider_id');
$eval_model_id = $query->get('eval_model_id');
// Run the test.
$results = $this->testRunner->runTest($test_id, $group_id, $provider_id, $model_id, $eval_provider_id, $eval_model_id);
$results['success'] = TRUE;
foreach ($results['results'] as $result_item) {
if (!$result_item['result']) {
$results['success'] = FALSE;
}
}
$results['entity'] = (int) $results['entity']->id();
return new JsonResponse(
$results,
);
}
/**
* Export a whole test group as YAML.
*
* @param int $group_id
* The test group ID.
*
* @return \Symfony\Component\HttpFoundation\Response
* The response with the YAML export.
*/
public function exportTestGroup($group_id) {
// Load the test group entity.
$test_group = $this->entityTypeManager()->getStorage('ai_agents_test_group')->load($group_id);
if (!$test_group) {
throw new \InvalidArgumentException(sprintf('Test group with ID %d not found.', $group_id));
}
// Create an YAML export of the test group.
$export = [
'label' => $test_group->label(),
'description' => $test_group->description->value,
'approval_percentage' => (int) $test_group->approval_percentage->value,
'config_reset' => $test_group->config_reset->value,
'tests' => [],
];
foreach ($test_group->tests as $test_wrapper) {
$test = $test_wrapper->entity->toArray();
$export['tests'][] = $test;
}
// Make a filename from the label.
$filename = preg_replace('/[^a-zA-Z0-9_]/', '_', $test_group->label());
$filename = strtolower($filename);
$filename = 'test_' . $filename . '.yaml';
$yaml_dump = Yaml::dump($export, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
return new Response($yaml_dump, 200, [
'Content-Type' => 'application/x-yaml',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
'Content-Length' => strlen($yaml_dump),
'Content-Transfer-Encoding' => 'binary',
'Cache-Control' => 'no-store, no-cache, must-revalidate',
'Pragma' => 'no-cache',
]);
}
}
