From 070486a9187bcb8360ea22f64cae51682080a9b8 Mon Sep 17 00:00:00 2001 From: liwenrui Date: Tue, 10 Oct 2023 09:30:25 +0800 Subject: [PATCH] * add exception for the scenario where the second step function call fails. --- module/ai/control.php | 10 ++++++++-- module/ai/lang/de.php | 3 +++ module/ai/lang/en.php | 3 +++ module/ai/lang/fr.php | 3 +++ module/ai/lang/zh-cn.php | 3 +++ module/ai/model.php | 43 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/module/ai/control.php b/module/ai/control.php index 540d88c0f6..a5a5860021 100644 --- a/module/ai/control.php +++ b/module/ai/control.php @@ -518,10 +518,16 @@ class ai extends control if(empty($location)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->ai->execute->failFormat, $this->lang->ai->execute->failReasons['noTargetForm']))); if(!empty($stop)) return header("location: $location", true, 302); - $response = $this->ai->executePrompt($prompt, $object); + try + { + $response = $this->ai->executePrompt($prompt, $object); + } + catch(AIResponseException $e) + { + return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->ai->execute->failFormat, $e->getMessage()))); + } if(is_int($response)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->ai->execute->failFormat, $this->lang->ai->execute->executeErrors["$response"]) . (empty($this->ai->errors) ? '' : implode(', ', $this->ai->errors)))); if(empty($response)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->ai->execute->failFormat, $this->lang->ai->execute->failReasons['noResponse']))); - $this->ai->setInjectData($prompt->targetForm, $response); $_SESSION['aiPrompt']['prompt'] = $prompt; diff --git a/module/ai/lang/de.php b/module/ai/lang/de.php index 5e7cc8282b..8c774bd008 100644 --- a/module/ai/lang/de.php +++ b/module/ai/lang/de.php @@ -796,3 +796,6 @@ $lang->ai->audit->backLocationList[1] = 'back to audit page and regenerate.'; $lang->ai->engineeredPrompts = new stdclass(); $lang->ai->engineeredPrompts->askForFunctionCalling = array((object)array('role' => 'user', 'content' => 'Please convert my next message into a function call.'), (object)array('role' => 'assistant', 'content' => 'Sure, I\'ll convert your next message into a function call.')); + +$lang->ai->aiResponseException = array(); +$lang->ai->aiResponseException['notFunctionCalling'] = 'The response is not a function calling'; diff --git a/module/ai/lang/en.php b/module/ai/lang/en.php index 5e7cc8282b..8c774bd008 100644 --- a/module/ai/lang/en.php +++ b/module/ai/lang/en.php @@ -796,3 +796,6 @@ $lang->ai->audit->backLocationList[1] = 'back to audit page and regenerate.'; $lang->ai->engineeredPrompts = new stdclass(); $lang->ai->engineeredPrompts->askForFunctionCalling = array((object)array('role' => 'user', 'content' => 'Please convert my next message into a function call.'), (object)array('role' => 'assistant', 'content' => 'Sure, I\'ll convert your next message into a function call.')); + +$lang->ai->aiResponseException = array(); +$lang->ai->aiResponseException['notFunctionCalling'] = 'The response is not a function calling'; diff --git a/module/ai/lang/fr.php b/module/ai/lang/fr.php index 5e7cc8282b..8c774bd008 100644 --- a/module/ai/lang/fr.php +++ b/module/ai/lang/fr.php @@ -796,3 +796,6 @@ $lang->ai->audit->backLocationList[1] = 'back to audit page and regenerate.'; $lang->ai->engineeredPrompts = new stdclass(); $lang->ai->engineeredPrompts->askForFunctionCalling = array((object)array('role' => 'user', 'content' => 'Please convert my next message into a function call.'), (object)array('role' => 'assistant', 'content' => 'Sure, I\'ll convert your next message into a function call.')); + +$lang->ai->aiResponseException = array(); +$lang->ai->aiResponseException['notFunctionCalling'] = 'The response is not a function calling'; diff --git a/module/ai/lang/zh-cn.php b/module/ai/lang/zh-cn.php index 11953d6b0b..0ba9bc0cf3 100644 --- a/module/ai/lang/zh-cn.php +++ b/module/ai/lang/zh-cn.php @@ -797,3 +797,6 @@ $lang->ai->audit->backLocationList[1] = '返回调试页面并重新生成'; $lang->ai->engineeredPrompts = new stdclass(); $lang->ai->engineeredPrompts->askForFunctionCalling = array((object)array('role' => 'user', 'content' => '请把我所发的下一条消息内容转换为 function 调用。'), (object)array('role' => 'assistant', 'content' => '好的,我会把下一条消息转换为 function 调用。')); + +$lang->ai->aiResponseException = array(); +$lang->ai->aiResponseException['notFunctionCalling'] = 'AI 提词执行返回值结构不正确,请重试(可能可以通过优化提词来解决)'; diff --git a/module/ai/model.php b/module/ai/model.php index 79893fb98a..4d605d7281 100644 --- a/module/ai/model.php +++ b/module/ai/model.php @@ -372,6 +372,7 @@ class aiModel extends model { /* Extract function call arguments. */ if(!empty($response->function_call)) return array($response->function_call->arguments); + throw new AIResponseException('notFunctionCalling', $response); } else { @@ -530,6 +531,7 @@ class aiModel extends model * @param array $options optional params, see https://platform.openai.com/docs/api-reference/chat/create * @access public * @return mixed false if error, array of JSON object if success + * @throws AIResponseException */ public function converseTwiceForJSON($messages, $schema, $options = array()) { @@ -1033,6 +1035,7 @@ class aiModel extends model * @param int|object $object object (or id) to execute prompt on. * @access public * @return string|int returns either JSON string or negative integer on error. + * @throws AIResponseException */ public function executePrompt($prompt, $object) { @@ -1728,3 +1731,43 @@ class aiModel extends model return true; } } + +/** + * Exception class for response from AI. + */ +class AIResponseException extends Exception +{ + /** + * Type of response error, error messages are defined in lang files with type as key. + * + * See `$lang->ai->aiResponseException`. + * + * @var string + * @access public + */ + public $type; + + /** + * Response with error. + * + * @var string|object + * @access public + */ + public $response; + + /** + * Create a AIResponseException, load error message from lang file. + * + * @param string $type + * @param string|object $response + * @access public + * @return void + */ + public function __construct($type, $response) + { + global $app; + $this->type = $type; + $this->response = $response; + $this->message = zget($app->lang->ai->aiResponseException, $type, ''); + } +}