Skip to content
Snippets Groups Projects

Issue #3519196: Better error handling when provider model is not properly configured

Open Issue #3519196: Better error handling when provider model is not properly configured
Open Sarvjeet Singh requested to merge issue/ai-3519196:3519196-handle-errors-for into 1.1.x
2 files
+ 176
107
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -236,135 +236,196 @@ final class ChatGenerator extends AiApiExplorerPluginBase {
*/
public function getResponse(array &$form, FormStateInterface $form_state): array {
// This runs on streamed.
$provider = $this->aiProviderHelper->generateAiProviderFromFormSubmit($form, $form_state, 'chat', 'chat');
$values = $form_state->getValues();
// Get the messages.
$messages = [];
// Get potential files.
$files = $this->getRequest()->files->all();
foreach ($values as $key => $value) {
if (str_starts_with($key, 'role_')) {
$index = substr($key, 5);
$role = $value;
$message = $values['message_' . $index];
// Load the file.
$image = "";
if (isset($files['files']['image_' . $index])) {
$raw_file = file_get_contents($files['files']['image_' . $index]->getPathname());
$image = new ImageFile($raw_file, $files['files']['image_' . $index]->getClientMimeType(), $files['files']['image_' . $index]->getClientOriginalName());
}
if ($role && $message) {
$images = [];
if ($image) {
$images[] = $image;
try {
$provider = $this->aiProviderHelper->generateAiProviderFromFormSubmit($form, $form_state, 'chat', 'chat');
$values = $form_state->getValues();
// Get the messages.
$messages = [];
// Get potential files.
$files = $this->getRequest()->files->all();
foreach ($values as $key => $value) {
if (str_starts_with($key, 'role_')) {
$index = substr($key, 5);
$role = $value;
$message = $values['message_' . $index];
// Load the file.
$image = "";
if (isset($files['files']['image_' . $index])) {
$raw_file = file_get_contents($files['files']['image_' . $index]->getPathname());
$image = new ImageFile($raw_file, $files['files']['image_' . $index]->getClientMimeType(), $files['files']['image_' . $index]->getClientOriginalName());
}
if ($role && $message) {
$images = [];
if ($image) {
$images[] = $image;
}
$messages[] = new ChatMessage($role, $message, $images);
}
$messages[] = new ChatMessage($role, $message, $images);
}
}
}
$functions = [];
$function_instances = [];
foreach ($values['function_calls'] as $function_call_name) {
$function_call = $this->functionCallPluginManager->createInstance($function_call_name);
$function_instances[$function_call->getFunctionName()] = $function_call;
$functions[] = $function_call->normalize();
}
$functions = [];
$function_instances = [];
foreach ($values['function_calls'] as $function_call_name) {
$function_call = $this->functionCallPluginManager->createInstance($function_call_name);
$function_instances[$function_call->getFunctionName()] = $function_call;
$functions[] = $function_call->normalize();
}
$input = new ChatInput($messages);
$input = new ChatInput($messages);
if (count($functions)) {
$input->setChatTools(new ToolsInput($functions));
}
if (count($functions)) {
$input->setChatTools(new ToolsInput($functions));
}
// Check for system message.
if ($form_state->getValue('system_message')) {
$provider->setChatSystemRole($form_state->getValue('system_message'));
}
// Check for system message.
if ($form_state->getValue('system_message')) {
$provider->setChatSystemRole($form_state->getValue('system_message'));
}
if ($form_state->getValue('json_schema')) {
$provider->setChatStructuredJsonSchema(Json::decode($form_state->getValue('json_schema')));
}
if ($form_state->getValue('json_schema')) {
$provider->setChatStructuredJsonSchema(Json::decode($form_state->getValue('json_schema')));
}
$message = NULL;
$response = NULL;
try {
// If we should stream.
if ($form_state->getValue('streamed')) {
$provider->streamedOutput();
$message = NULL;
$response = NULL;
try {
// If we should stream.
if ($form_state->getValue('streamed')) {
$provider->streamedOutput();
}
$response = $provider->chat($input, $form_state->getValue('chat_ai_model'), [
'chat_generation',
'ai_api_explorer',
])->getNormalized();
}
$response = $provider->chat($input, $form_state->getValue('chat_ai_model'), [
'chat_generation',
'ai_api_explorer',
])->getNormalized();
}
catch (\Exception $e) {
$message = $this->explorerHelper->renderException($e);
}
$code = '';
$tools_output = '';
if ($response) {
if (method_exists($response, 'getTools') && $response->getTools()) {
$tools_output = $this->getToolsOutput($function_instances, $response->getTools(), $form_state->getValue('execute'));
catch (\TypeError $e) {
$message = $this->t('The AI provider could not be used. Please make sure a model is selected and the provider is properly configured.');
}
// Generation code for normalization.
$code = $this->normalizeCodeExample($provider, $form_state, $messages);
}
if (is_object($response) && get_class($response) == ChatMessage::class) {
$output = $response->getText();
if ($form_state->getValue('json_schema')) {
// Decode && encode nicely.
$json = json_encode(Json::decode($output), JSON_PRETTY_PRINT);
if (!empty($json)) {
$output = '<pre>' . $json . '</pre>';
catch (\Exception $e) {
$message = $this->explorerHelper->renderException($e);
}
$code = '';
$tools_output = '';
if ($response) {
if (method_exists($response, 'getTools') && $response->getTools()) {
$tools_output = $this->getToolsOutput($function_instances, $response->getTools(), $form_state->getValue('execute'));
}
// Generation code for normalization.
$code = $this->normalizeCodeExample($provider, $form_state, $messages);
}
$form['middle']['response']['#context']['ai_response']['role'] = [
'#type' => 'html_tag',
'#tag' => 'h4',
'#value' => 'Role: ' . $response->getRole(),
];
$form['middle']['response']['#context']['ai_response']['text'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $output,
];
if ($tools_output) {
$form['middle']['response']['#context']['ai_response']['tools_wrapper'] = [
'#type' => 'details',
'#title' => $this->t('Tools Output'),
'#open' => TRUE,
if (is_object($response) && get_class($response) == ChatMessage::class) {
$output = $response->getText();
if ($form_state->getValue('json_schema')) {
// Decode && encode nicely.
$json = json_encode(Json::decode($output), JSON_PRETTY_PRINT);
if (!empty($json)) {
$output = '<pre>' . $json . '</pre>';
}
}
$form['middle']['response']['#context']['ai_response']['role'] = [
'#type' => 'html_tag',
'#tag' => 'h4',
'#value' => 'Role: ' . $response->getRole(),
];
$form['middle']['response']['#context']['ai_response']['tools_wrapper']['tools'] = [
$form['middle']['response']['#context']['ai_response']['text'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $tools_output,
'#tag' => 'p',
'#value' => $output,
];
if ($tools_output) {
$form['middle']['response']['#context']['ai_response']['tools_wrapper'] = [
'#type' => 'details',
'#title' => $this->t('Tools Output'),
'#open' => TRUE,
];
$form['middle']['response']['#context']['ai_response']['tools_wrapper']['tools'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $tools_output,
];
}
$form['middle']['response']['#context']['ai_response']['code'] = $code;
$form_state->setRebuild();
return $form['middle'];
}
$form['middle']['response']['#context']['ai_response']['code'] = $code;
$form_state->setRebuild();
return $form['middle'];
}
elseif ($response instanceof StreamedChatMessageIteratorInterface) {
$http_response = new StreamedResponse();
$http_response->setCallback(function () use ($response, $code) {
foreach ($response as $key => $chat_message) {
if ($chat_message->getRole() && !$key) {
echo '<h4>Role: ' . $chat_message->getRole() . "</h4><p>";
elseif ($response instanceof StreamedChatMessageIteratorInterface) {
$http_response = new StreamedResponse();
$http_response->setCallback(function () use ($response, $code) {
foreach ($response as $key => $chat_message) {
if ($chat_message->getRole() && !$key) {
echo '<h4>Role: ' . $chat_message->getRole() . "</h4><p>";
}
echo $chat_message->getText();
ob_flush();
flush();
}
echo $chat_message->getText();
echo $this->renderer->render($code);
ob_flush();
flush();
});
$form_state->setResponse($http_response);
}
else {
$form['middle']['response']['#context']['ai_response'] = [
'heading' => [
'#type' => 'html_tag',
'#tag' => 'h3',
'#value' => $message ? $this->t('Error') : $this->t('Response will appear here.'),
],
];
if ($message) {
$form['middle']['response']['#context']['ai_response']['message'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $message,
'#attributes' => [
'class' => ['ai-text-response', 'ai-error-message'],
],
];
}
echo $this->renderer->render($code);
ob_flush();
flush();
});
$form_state->setResponse($http_response);
$form_state->setRebuild();
return $form['middle'];
}
}
else {
$form['middle']['response']['#context']['ai_response']['#markup'] = $message;
catch (\TypeError $e) {
$form['middle']['response']['#context']['ai_response'] = [
'heading' => [
'#type' => 'html_tag',
'#tag' => 'h3',
'#value' => $this->t('Configuration Error'),
],
'message' => [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $this->t('The AI provider could not be used. Please make sure a model is selected and the provider is properly configured.'),
'#attributes' => [
'class' => ['ai-text-response', 'ai-error-message'],
],
],
];
$form_state->setRebuild();
return $form['middle'];
}
catch (\Exception $e) {
$form['middle']['response']['#context']['ai_response'] = [
'heading' => [
'#type' => 'html_tag',
'#tag' => 'h3',
'#value' => $this->t('Error'),
],
'message' => [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $this->explorerHelper->renderException($e),
'#attributes' => [
'class' => ['ai-text-response', 'ai-error-message'],
],
],
];
$form_state->setRebuild();
return $form['middle'];
}
Loading