Skip to content
Snippets Groups Projects
Commit 3bcd6488 authored by Mark Jones's avatar Mark Jones
Browse files

Issue #3487485: Add AiEvaluation entity view route and update listing to link to it.

parent 621478ae
No related branches found
No related tags found
1 merge request!6Issue #3487485: Add AiEvaluation entity view route and update listing to link to it.
<?php
use Drupal\ai_assistant_api\AiAssistantInterface;
use Drupal\ai_evaluations\Entity\AIEvaluation;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Link;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
/**
* Implements hook_cron.
*/
......@@ -128,3 +129,83 @@ function ai_evaluations_entity_operation(EntityInterface $entity) {
return $operations;
}
/**
* Implements hook_entity_view().
*/
function ai_evaluations_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if (!$entity instanceof AIEvaluation) {
return;
}
// @Todo Move to field formatter or similar.
$build['agents'] = [
'#type' => 'container',
'#weight' => 100,
'#cache' => ['max-age' => '-1'],
];
$agent_results = [];
$result_storage = \Drupal::entityTypeManager()->getStorage('ai_agent_result');
$agent_query = $result_storage->getQuery();
$agent_query->accessCheck(FALSE);
$agent_query->condition('ai_evaluation', $entity->id());
$agent_query->sort('id', 'ASC');
if ($result = $agent_query->execute()) {
$agent_results = $result_storage->loadMultiple($result);
}
$build['messages'] = [
'#type' => 'container',
'title' => ['#markup' => '<h2>' . new TranslatableMarkup('Messages') . '</h2>'],
];
foreach ($entity->get('messages')->getValue() as $delta => $message) {
$message_agents = [];
foreach ($agent_results as $agent_result) {
if ((int) $agent_result->get('created')->value === $message['timestamp']) {
$message_agents[] = [
'#type' => 'details',
'#title' => $agent_result->label(),
'provider' => [
'#markup' => new TranslatableMarkup('<h3>AI Provider info</h3>')
. '<p>' . $agent_result->get('ai_provider_info')->value . '</p>',
],
'prompt' => [
'#markup' => new TranslatableMarkup('<h3>Prompt</h3>')
. '<pre>' . ($agent_result->get('prompt_used')->value) . '</pre>',
],
'question' => [
'#markup' => new TranslatableMarkup('<h3>Question</h3>')
. '<pre>' . ($agent_result->get('question')->value) . '</pre>',
],
'response_given' => [
'#markup' => new TranslatableMarkup('<h3>Response given</h3>')
. '<pre>' . ($agent_result->get('response_given')->value) . '</pre>',
],
'detailed_output' => [
'#markup' => new TranslatableMarkup('<h3>Detailed output</h3>')
. '<pre>' . ($agent_result->get('detailed_output')->value) . '</pre>',
],
];
}
}
$build['messages'][$delta] = [
'#type' => 'details',
'#title' => new TranslatableMarkup('@role message', [
'@role' => $message['role'],
]),
'message' => [
'#markup' => '<h3>' . new TranslatableMarkup('Message') . '</h3><pre>' . $message['message'] . '</pre>',
],
'time' => [
'#markup' => '<h3>' . new TranslatableMarkup('Time') . '</h3><pre>' . $message['timestamp'] . '</pre>',
],
'agent' => $message_agents ?? [],
];
$build['evaluation'] = [
'#markup' => '<h3>' . new TranslatableMarkup('Evaluation value') . '</h3><pre>' . $entity->get('value')->value . '</pre>',
];
}
}
......@@ -469,6 +469,59 @@ display:
multi_type: separator
separator: ', '
field_api_classes: false
view_ai_evaluation:
id: view_ai_evaluation
table: ai_evaluation
field: view_ai_evaluation
relationship: none
group_type: group
admin_label: ''
entity_type: ai_evaluation
plugin_id: entity_link
label: View
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
text: View
output_url_as_text: false
absolute: false
pager:
type: full
options:
......@@ -508,7 +561,23 @@ display:
type: tag
options: { }
empty: { }
sorts: { }
sorts:
created:
id: created
table: ai_evaluation
field: created
relationship: none
group_type: group
admin_label: ''
entity_type: ai_evaluation
entity_field: created
plugin_id: date
order: DESC
expose:
label: ''
field_identifier: ''
exposed: false
granularity: second
arguments:
assistant:
id: assistant
......
......@@ -50,8 +50,8 @@ use Drupal\user\EntityOwnerTrait;
* links = {
* "collection" = "/admin/content/ai-evaluation",
* "add-form" = "/admin/config/ai/ai-evaluations/add",
* "canonical" = "/admin/config/ai/ai-evaluations/{ai_evaluation}",
* "edit-form" = "/admin/config/ai/ai-evaluations/{ai_evaluation}",
* "canonical" = "/admin/config/ai/ai-assistant/{ai_assistant}/evaluation/{ai_evaluation}",
* "edit-form" = "/admin/config/ai/ai-assistant/{ai_assistant}/evaluation/{ai_evaluation}/edit",
* "delete-form" = "/admin/config/ai/ai-evaluations/{ai_evaluation}/delete",
* "delete-multiple-form" = "/admin/content/ai-evaluation/delete-multiple",
* },
......@@ -63,6 +63,15 @@ final class AIEvaluation extends ContentEntityBase implements AIEvaluationInterf
use EntityChangedTrait;
use EntityOwnerTrait;
/**
* {@inheritdoc}
*/
protected function urlRouteParameters($rel) {
return parent::urlRouteParameters($rel) + [
'ai_assistant' => $this->get('assistant')->target_id,
];
}
/**
* {@inheritdoc}
*/
......@@ -166,6 +175,7 @@ final class AIEvaluation extends ContentEntityBase implements AIEvaluationInterf
$agent_storage = $this->entityTypeManager()->getStorage('ai_agent_result');
$query = $agent_storage->getQuery();
$query->condition('thread_id', $this->thread_id->value);
$query->condition('ai_evaluation', NULL, 'IS NULL');
$query->accessCheck(FALSE);
$result = $query->execute();
foreach ($result as $id) {
......
......@@ -83,8 +83,8 @@ class PostRequestEventSubscriber implements EventSubscriberInterface {
if (strpos($tag, 'ai_agents_prompt_') !== FALSE) {
$file = str_replace('ai_agents_prompt_', '', $tag);
}
if (strpos($tag, 'thread_id__') !== FALSE) {
$thread_id = str_replace('thread_id__', '', $tag);
if (strpos($tag, 'ai_assistant_thread_') !== FALSE) {
$thread_id = str_replace('ai_assistant_thread_', '', $tag);
}
}
$storage = $this->entityTypeManager->getStorage('ai_agent_result');
......@@ -104,6 +104,35 @@ class PostRequestEventSubscriber implements EventSubscriberInterface {
]);
$result->save();
}
elseif (in_array('ai_assistant_api', $event->getTags())) {
foreach ($event->getTags() as $tag) {
if (strpos($tag, 'ai_assistant_api_preprompt_') !== FALSE) {
$label = str_replace('ai_assistant_api_preprompt_', '', $tag);
}
if (strpos($tag, 'ai_assistant_api_assistant_message_') !== FALSE) {
$label = str_replace('ai_assistant_api_assistant_message_', '', $tag);
}
if (strpos($tag, 'ai_assistant_thread_') !== FALSE) {
$thread_id = str_replace('ai_assistant_thread_', '', $tag);
}
}
$storage = $this->entityTypeManager->getStorage('ai_agent_result');
$response = $event->getOutput()->getNormalized();
$formatted = is_array($response) ? Json::encode($response) : $response;
$provider_info = $event->getProviderId() . "\n" . $event->getModelId() . "\n" . Json::encode($event->getConfiguration());
$result = $storage->create([
'label' => $label ?? '',
'thread_id' => $thread_id ?? '',
'action' => 'sub_agent',
'log_status' => 'notice',
'ai_provider_info' => $provider_info,
'question' => $event->getInput()->getMessages()[0]->getText(),
'prompt_used' => $event->getDebugData()['chat_system_role'] ?? '',
'response_given' => is_string($formatted) ?? $formatted->getText(),
'detailed_output' => Json::encode($event->getOutput()->getRawOutput()),
]);
$result->save();
}
}
}
......@@ -6,7 +6,6 @@ namespace Drupal\ai_evaluations\Routing;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
use Symfony\Component\Routing\Route;
/**
* Provides HTML routes for entities with administrative pages.
......@@ -16,8 +15,13 @@ final class AIEvaluationHtmlRouteProvider extends AdminHtmlRouteProvider {
/**
* {@inheritdoc}
*/
protected function getCanonicalRoute(EntityTypeInterface $entity_type): ?Route {
return $this->getEditFormRoute($entity_type);
protected function getCanonicalRoute(EntityTypeInterface $entity_type) {
$route = parent::getCanonicalRoute($entity_type);
$params = $route->getOption('parameters');
$route->setOption('parameters', $params + [
'ai_assistant' => ['type' => 'entity:' . 'ai_assistant'],
]);
return $route;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment