Merge branch 'ai-next/ernie' into 18.x
This commit is contained in:
+36
-9
@@ -2,10 +2,14 @@
|
||||
$config->ai->vendorList = array();
|
||||
$config->ai->vendorList['openai']['requiredFields'] = array('key');
|
||||
$config->ai->vendorList['azure']['requiredFields'] = array('key', 'resource', 'deployment');
|
||||
$config->ai->vendorList['baidu']['requiredFields'] = array('key', 'secret');
|
||||
|
||||
$config->ai->models = array('openai-gpt35' => 'openai', 'baidu-ernie' => 'ernie');
|
||||
|
||||
/* OpenAI GPT configurations. */
|
||||
$config->ai->openai = new stdclass();
|
||||
$config->ai->openai->api = new stdclass();
|
||||
$config->ai->openai->api->vendor = array('openai', 'azure');
|
||||
$config->ai->openai->api->vendor = array('openai', 'azure');
|
||||
$config->ai->openai->api->openai = new stdclass();
|
||||
$config->ai->openai->api->openai->version = 'v1'; // OpenAI API version, required.
|
||||
$config->ai->openai->api->openai->format = 'https://api.openai.com/%s/%s'; // OpenAI API format, args: API version, API name.
|
||||
@@ -16,35 +20,58 @@ $config->ai->openai->api->azure->deployment = 'the-first-gpt'; /
|
||||
$config->ai->openai->api->azure->apiVersion = '2023-07-01-preview'; // Azure OpenAI API version, required.
|
||||
$config->ai->openai->api->azure->format = 'https://%s.openai.azure.com/openai/deployments/%s/%s?api-version=%s'; // Azure API format, args: resource name, deployment name, API name, API version.
|
||||
$config->ai->openai->api->azure->authFormat = 'api-key: %s'; // Azure API auth header format.
|
||||
$config->ai->openai->api->methods = array('function' => 'chat/completions', 'chat' => 'chat/completions', 'completion' => 'completions', 'edit' => 'edits');
|
||||
$config->ai->openai->api->methods = array('function' => 'chat/completions', 'chat' => 'chat/completions', 'completion' => 'completions');
|
||||
|
||||
$config->ai->openai->params = new stdclass();
|
||||
$config->ai->openai->params->chat = new stdclass();
|
||||
$config->ai->openai->params->function = new stdclass();
|
||||
$config->ai->openai->params->completion = new stdclass();
|
||||
$config->ai->openai->params->edit = new stdclass();
|
||||
$config->ai->openai->params->chat->required = array('messages');
|
||||
$config->ai->openai->params->chat->optional = array('max_tokens', 'temperature', 'top_p', 'n', 'stream', 'stop', 'presence_penalty', 'frequency_penalty', 'logit_bias', 'user');
|
||||
$config->ai->openai->params->function->required = array('messages', 'functions', 'function_call');
|
||||
$config->ai->openai->params->function->optional = array('max_tokens', 'temperature', 'top_p', 'n', 'stream', 'stop', 'presence_penalty', 'frequency_penalty', 'logit_bias', 'user');
|
||||
$config->ai->openai->params->completion->required = array('prompt', 'max_tokens');
|
||||
$config->ai->openai->params->completion->optional = array('suffix', 'temperature', 'top_p', 'n', 'stream', 'logprobs', 'echo', 'stop', 'presence_penalty', 'frequency_penalty', 'best_of', 'logit_bias', 'user');
|
||||
$config->ai->openai->params->edit->required = array('input', 'instruction');
|
||||
$config->ai->openai->params->edit->optional = array('temperature', 'top_p', 'n');
|
||||
|
||||
$config->ai->openai->model = new stdclass();
|
||||
$config->ai->openai->model->chat = 'gpt-3.5-turbo';
|
||||
$config->ai->openai->model->function = 'gpt-3.5-turbo-0613';
|
||||
$config->ai->openai->model->completion = 'text-davinci-003';
|
||||
$config->ai->openai->model->edit = 'text-davinci-edit-001';
|
||||
$config->ai->openai->model->function = 'gpt-3.5-turbo';
|
||||
$config->ai->openai->model->completion = 'gpt-3.5-turbo-instruct';
|
||||
|
||||
$config->ai->openai->contentTypeMapping = array('Content-Type: application/json' => array('', 'function', 'chat', 'completion', 'edit'), 'Content-Type: multipart/form-data' => array());
|
||||
$config->ai->openai->contentTypeMapping = array('Content-Type: application/json' => array('', 'function', 'chat', 'completion'), 'Content-Type: multipart/form-data' => array());
|
||||
$config->ai->openai->contentType = array();
|
||||
foreach($config->ai->openai->contentTypeMapping as $contentType => $apis)
|
||||
{
|
||||
foreach($apis as $api) $config->ai->openai->contentType[$api] = $contentType;
|
||||
}
|
||||
|
||||
/* Baidu ERNIE configurations. */
|
||||
$config->ai->ernie = new stdclass();
|
||||
$config->ai->ernie->api = new stdclass();
|
||||
$config->ai->ernie->api->vendor = array('baidu');
|
||||
$config->ai->ernie->api->baidu = new stdclass();
|
||||
$config->ai->ernie->api->baidu->format = 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=%s'; // ERNIE API format, arg: access_token (obtained from bce oauth).
|
||||
$config->ai->ernie->api->baidu->auth = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s'; // BCE auth URL format, args: client_id, client_secret.
|
||||
|
||||
$config->ai->ernie->params = new stdclass();
|
||||
$config->ai->ernie->params->chat = new stdclass();
|
||||
$config->ai->ernie->params->function = new stdclass();
|
||||
$config->ai->ernie->params->chat->required = array('messages');
|
||||
$config->ai->ernie->params->chat->optional = array('temperature', 'top_p', 'penalty_score', 'stream', 'user_id');
|
||||
$config->ai->ernie->params->function->required = array('messages', 'functions');
|
||||
$config->ai->ernie->params->function->optional = array('temperature', 'top_p', 'penalty_score', 'stream', 'user_id');
|
||||
|
||||
$config->ai->ernie->model = new stdclass();
|
||||
$config->ai->ernie->model->chat = 'ernie-bot-turbo';
|
||||
$config->ai->ernie->model->function = 'ernie-bot-turbo';
|
||||
|
||||
$config->ai->ernie->contentTypeMapping = array('Content-Type: application/json' => array('', 'function', 'chat'), 'Content-Type: multipart/form-data' => array());
|
||||
$config->ai->ernie->contentType = array();
|
||||
foreach($config->ai->ernie->contentTypeMapping as $contentType => $apis)
|
||||
{
|
||||
foreach($apis as $api) $config->ai->ernie->contentType[$api] = $contentType;
|
||||
}
|
||||
|
||||
/* Required fields of forms. */
|
||||
$config->ai->createprompt = new stdclass();
|
||||
$config->ai->testPrompt = new stdclass();
|
||||
|
||||
+22
-8
@@ -81,7 +81,7 @@ class ai extends control
|
||||
{
|
||||
$modelConfig = fixer::input('post')->get();
|
||||
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->openaiVendorList) : $modelConfig->vendor;
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($this->lang->ai->models->vendorList->{empty($modelConfig->type) ? key($this->lang->ai->models->typeList) : $modelConfig->type}) : $modelConfig->vendor;
|
||||
$vendorRequiredFields = $this->config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
|
||||
$errors = array();
|
||||
@@ -128,7 +128,7 @@ class ai extends control
|
||||
{
|
||||
$modelConfig = fixer::input('post')->get();
|
||||
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->openaiVendorList) : $modelConfig->vendor;
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($this->lang->ai->models->vendorList->{empty($modelConfig->type) ? key($this->lang->ai->models->typeList) : $modelConfig->type}) : $modelConfig->vendor;
|
||||
$vendorRequiredFields = $this->config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
|
||||
$errors = array();
|
||||
@@ -145,12 +145,10 @@ class ai extends control
|
||||
|
||||
$this->ai->setConfig($modelConfig);
|
||||
|
||||
if($currentVendor == 'azure')
|
||||
if($this->config->ai->models[$modelConfig->type] == 'ernie' || $currentVendor == 'azure')
|
||||
{
|
||||
$messages = array(
|
||||
(object)array('role' => 'user', 'content' => 'Hello?')
|
||||
);
|
||||
$result = $this->ai->converse($messages);
|
||||
$messages = array((object)array('role' => 'user', 'content' => 'test'));
|
||||
$result = $this->ai->converse($messages, array('maxTokens' => 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -520,7 +518,23 @@ 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);
|
||||
/* Execute prompt and catch exceptions. */
|
||||
try
|
||||
{
|
||||
$response = $this->ai->executePrompt($prompt, $object);
|
||||
}
|
||||
catch(AIResponseException $e)
|
||||
{
|
||||
$output = array('result' => 'fail', 'message' => sprintf($this->lang->ai->execute->failFormat, $e->getMessage()));
|
||||
|
||||
/* Audition shall quit on such exception. */
|
||||
if(isset($_SESSION['auditPrompt']) && time() - $_SESSION['auditPrompt']['time'] < 10 * 60)
|
||||
{
|
||||
$output['locate'] = $this->inlink('promptAudit', "promptID=$promptId&objectId=$objectId&exit=true");
|
||||
}
|
||||
return $this->send($output);
|
||||
}
|
||||
|
||||
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'])));
|
||||
|
||||
|
||||
+30
-23
@@ -59,25 +59,26 @@ $lang->ai->validate->dirtyForm = 'The design step of %s has changed. Do you
|
||||
$lang->ai->validate->nameNotUnique = 'A prompt with the same name already exists, please change the name.';
|
||||
|
||||
$lang->ai->prompts = new stdclass();
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->modelNeutral = 'Model Neutral';
|
||||
|
||||
$lang->ai->prompts->summary = 'There are %s prompts on this page.';
|
||||
|
||||
@@ -423,11 +424,11 @@ $lang->ai->models->statusList['off'] = 'Disable';
|
||||
|
||||
$lang->ai->models->typeList = array();
|
||||
$lang->ai->models->typeList['openai-gpt35'] = 'OpenAI / GPT-3.5';
|
||||
// $lang->ai->models->typeList['azure-gpt35'] = 'Azure / GPT-3.5';
|
||||
$lang->ai->models->typeList['baidu-ernie'] = 'Baidu / ERNIE';
|
||||
|
||||
$lang->ai->models->openaiVendorList = array();
|
||||
$lang->ai->models->openaiVendorList['openai'] = 'OpenAI';
|
||||
$lang->ai->models->openaiVendorList['azure'] = 'Azure';
|
||||
$lang->ai->models->vendorList = new stdclass();
|
||||
$lang->ai->models->vendorList->{'openai-gpt35'} = array('openai' => 'OpenAI', 'azure' => 'Azure');
|
||||
$lang->ai->models->vendorList->{'baidu-ernie'} = array('baidu' => 'Baidu Qianfan LLM Platform');
|
||||
|
||||
$lang->ai->models->proxyTypes = array();
|
||||
$lang->ai->models->proxyTypes[''] = 'No Proxy';
|
||||
@@ -793,3 +794,9 @@ $lang->ai->audit->exit = 'Exit Audit';
|
||||
$lang->ai->audit->backLocationList = array();
|
||||
$lang->ai->audit->backLocationList[0] = 'back to audit page.';
|
||||
$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';
|
||||
|
||||
+30
-23
@@ -59,25 +59,26 @@ $lang->ai->validate->dirtyForm = 'The design step of %s has changed. Do you
|
||||
$lang->ai->validate->nameNotUnique = 'A prompt with the same name already exists, please change the name.';
|
||||
|
||||
$lang->ai->prompts = new stdclass();
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->modelNeutral = 'Model Neutral';
|
||||
|
||||
$lang->ai->prompts->summary = 'There are %s prompts on this page.';
|
||||
|
||||
@@ -423,11 +424,11 @@ $lang->ai->models->statusList['off'] = 'Disable';
|
||||
|
||||
$lang->ai->models->typeList = array();
|
||||
$lang->ai->models->typeList['openai-gpt35'] = 'OpenAI / GPT-3.5';
|
||||
// $lang->ai->models->typeList['azure-gpt35'] = 'Azure / GPT-3.5';
|
||||
$lang->ai->models->typeList['baidu-ernie'] = 'Baidu / ERNIE';
|
||||
|
||||
$lang->ai->models->openaiVendorList = array();
|
||||
$lang->ai->models->openaiVendorList['openai'] = 'OpenAI';
|
||||
$lang->ai->models->openaiVendorList['azure'] = 'Azure';
|
||||
$lang->ai->models->vendorList = new stdclass();
|
||||
$lang->ai->models->vendorList->{'openai-gpt35'} = array('openai' => 'OpenAI', 'azure' => 'Azure');
|
||||
$lang->ai->models->vendorList->{'baidu-ernie'} = array('baidu' => 'Baidu Qianfan LLM Platform');
|
||||
|
||||
$lang->ai->models->proxyTypes = array();
|
||||
$lang->ai->models->proxyTypes[''] = 'No Proxy';
|
||||
@@ -793,3 +794,9 @@ $lang->ai->audit->exit = 'Exit Audit';
|
||||
$lang->ai->audit->backLocationList = array();
|
||||
$lang->ai->audit->backLocationList[0] = 'back to audit page.';
|
||||
$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';
|
||||
|
||||
+30
-23
@@ -59,25 +59,26 @@ $lang->ai->validate->dirtyForm = 'The design step of %s has changed. Do you
|
||||
$lang->ai->validate->nameNotUnique = 'A prompt with the same name already exists, please change the name.';
|
||||
|
||||
$lang->ai->prompts = new stdclass();
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->common = 'Prompt';
|
||||
$lang->ai->prompts->emptyList = 'No prompts yet.';
|
||||
$lang->ai->prompts->create = 'Create Prompt';
|
||||
$lang->ai->prompts->edit = 'Edit Prompt';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = 'Name';
|
||||
$lang->ai->prompts->description = 'Description';
|
||||
$lang->ai->prompts->createdBy = 'Creator';
|
||||
$lang->ai->prompts->createdDate = 'Created Date';
|
||||
$lang->ai->prompts->targetForm = 'Target Form';
|
||||
$lang->ai->prompts->funcDesc = 'Function Description';
|
||||
$lang->ai->prompts->deleted = 'Deleted';
|
||||
$lang->ai->prompts->stage = 'Stage';
|
||||
$lang->ai->prompts->basicInfo = 'Basic Info';
|
||||
$lang->ai->prompts->editInfo = 'Edit Info';
|
||||
$lang->ai->prompts->createdBy = 'Created By';
|
||||
$lang->ai->prompts->publishedBy = 'Published By';
|
||||
$lang->ai->prompts->draftedBy = 'Drafted By';
|
||||
$lang->ai->prompts->lastEditor = 'Last Editor';
|
||||
$lang->ai->prompts->modelNeutral = 'Model Neutral';
|
||||
|
||||
$lang->ai->prompts->summary = 'There are %s prompts on this page.';
|
||||
|
||||
@@ -423,11 +424,11 @@ $lang->ai->models->statusList['off'] = 'Disable';
|
||||
|
||||
$lang->ai->models->typeList = array();
|
||||
$lang->ai->models->typeList['openai-gpt35'] = 'OpenAI / GPT-3.5';
|
||||
// $lang->ai->models->typeList['azure-gpt35'] = 'Azure / GPT-3.5';
|
||||
$lang->ai->models->typeList['baidu-ernie'] = 'Baidu / ERNIE';
|
||||
|
||||
$lang->ai->models->openaiVendorList = array();
|
||||
$lang->ai->models->openaiVendorList['openai'] = 'OpenAI';
|
||||
$lang->ai->models->openaiVendorList['azure'] = 'Azure';
|
||||
$lang->ai->models->vendorList = new stdclass();
|
||||
$lang->ai->models->vendorList->{'openai-gpt35'} = array('openai' => 'OpenAI', 'azure' => 'Azure');
|
||||
$lang->ai->models->vendorList->{'baidu-ernie'} = array('baidu' => 'Baidu Qianfan LLM Platform');
|
||||
|
||||
$lang->ai->models->proxyTypes = array();
|
||||
$lang->ai->models->proxyTypes[''] = 'No Proxy';
|
||||
@@ -793,3 +794,9 @@ $lang->ai->audit->exit = 'Exit Audit';
|
||||
$lang->ai->audit->backLocationList = array();
|
||||
$lang->ai->audit->backLocationList[0] = 'back to audit page.';
|
||||
$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';
|
||||
|
||||
+31
-23
@@ -59,25 +59,26 @@ $lang->ai->validate->dirtyForm = '%s的参数配置已变动,是否保存
|
||||
$lang->ai->validate->nameNotUnique = '该名称已使用,请尝试其他名称。';
|
||||
|
||||
$lang->ai->prompts = new stdclass();
|
||||
$lang->ai->prompts->common = '提词';
|
||||
$lang->ai->prompts->emptyList = '暂时没有提词。';
|
||||
$lang->ai->prompts->create = '创建提词';
|
||||
$lang->ai->prompts->edit = '编辑提词';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = '名称';
|
||||
$lang->ai->prompts->description = '描述';
|
||||
$lang->ai->prompts->createdBy = '创建者';
|
||||
$lang->ai->prompts->createdDate = '创建时间';
|
||||
$lang->ai->prompts->targetForm = '表单';
|
||||
$lang->ai->prompts->funcDesc = '功能描述';
|
||||
$lang->ai->prompts->deleted = '已删除';
|
||||
$lang->ai->prompts->stage = '阶段';
|
||||
$lang->ai->prompts->basicInfo = '基本信息';
|
||||
$lang->ai->prompts->editInfo = '创建编辑';
|
||||
$lang->ai->prompts->createdBy = '由谁创建';
|
||||
$lang->ai->prompts->publishedBy = '由谁发布';
|
||||
$lang->ai->prompts->draftedBy = '由谁下架';
|
||||
$lang->ai->prompts->lastEditor = '最后编辑';
|
||||
$lang->ai->prompts->common = '提词';
|
||||
$lang->ai->prompts->emptyList = '暂时没有提词。';
|
||||
$lang->ai->prompts->create = '创建提词';
|
||||
$lang->ai->prompts->edit = '编辑提词';
|
||||
$lang->ai->prompts->id = 'ID';
|
||||
$lang->ai->prompts->name = '名称';
|
||||
$lang->ai->prompts->description = '描述';
|
||||
$lang->ai->prompts->createdBy = '创建者';
|
||||
$lang->ai->prompts->createdDate = '创建时间';
|
||||
$lang->ai->prompts->targetForm = '表单';
|
||||
$lang->ai->prompts->funcDesc = '功能描述';
|
||||
$lang->ai->prompts->deleted = '已删除';
|
||||
$lang->ai->prompts->stage = '阶段';
|
||||
$lang->ai->prompts->basicInfo = '基本信息';
|
||||
$lang->ai->prompts->editInfo = '创建编辑';
|
||||
$lang->ai->prompts->createdBy = '由谁创建';
|
||||
$lang->ai->prompts->publishedBy = '由谁发布';
|
||||
$lang->ai->prompts->draftedBy = '由谁下架';
|
||||
$lang->ai->prompts->lastEditor = '最后编辑';
|
||||
$lang->ai->prompts->modelNeutral = '通用';
|
||||
|
||||
$lang->ai->prompts->summary = '本页共 %s 个提词。';
|
||||
|
||||
@@ -400,6 +401,7 @@ $lang->ai->models->common = '语言模型';
|
||||
$lang->ai->models->type = '语言模型';
|
||||
$lang->ai->models->vendor = '供应商';
|
||||
$lang->ai->models->key = 'API Key';
|
||||
$lang->ai->models->secret = 'Secret Key';
|
||||
$lang->ai->models->resource = 'Resource';
|
||||
$lang->ai->models->deployment = 'Deployment';
|
||||
$lang->ai->models->proxyType = '代理类型';
|
||||
@@ -423,11 +425,11 @@ $lang->ai->models->statusList['off'] = '停用';
|
||||
|
||||
$lang->ai->models->typeList = array();
|
||||
$lang->ai->models->typeList['openai-gpt35'] = 'OpenAI / GPT-3.5';
|
||||
// $lang->ai->models->typeList['azure-gpt35'] = 'Azure / GPT-3.5';
|
||||
$lang->ai->models->typeList['baidu-ernie'] = '百度 / 文心一言';
|
||||
|
||||
$lang->ai->models->openaiVendorList = array();
|
||||
$lang->ai->models->openaiVendorList['openai'] = 'OpenAI';
|
||||
$lang->ai->models->openaiVendorList['azure'] = 'Azure';
|
||||
$lang->ai->models->vendorList = new stdclass();
|
||||
$lang->ai->models->vendorList->{'openai-gpt35'} = array('openai' => 'OpenAI', 'azure' => 'Azure');
|
||||
$lang->ai->models->vendorList->{'baidu-ernie'} = array('baidu' => '百度千帆大模型平台');
|
||||
|
||||
$lang->ai->models->proxyTypes = array();
|
||||
$lang->ai->models->proxyTypes[''] = '不使用代理';
|
||||
@@ -793,3 +795,9 @@ $lang->ai->audit->exit = '退出调试';
|
||||
$lang->ai->audit->backLocationList = array();
|
||||
$lang->ai->audit->backLocationList[0] = '返回调试页面';
|
||||
$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 提词执行返回值结构不正确,请重试(可能可以通过优化提词来解决)';
|
||||
|
||||
+172
-25
@@ -79,22 +79,61 @@ class aiModel extends model
|
||||
*/
|
||||
private function makeRequest($type, $data, $timeout = 10)
|
||||
{
|
||||
$modelType = $this->config->ai->models[$this->modelConfig->type];
|
||||
$modelVendor = $this->modelConfig->vendor;
|
||||
|
||||
/* Try encoding data to json, handles both encoded json and raw data. */
|
||||
$postData = json_encode($data);
|
||||
if(json_last_error()) $postData = $data;
|
||||
|
||||
/* Set auth and content-type headers. */
|
||||
$requestHeaders = array(sprintf($this->config->ai->openai->api->{$this->modelConfig->vendor}->authFormat, $this->modelConfig->key));
|
||||
$requestHeaders[] = isset($this->config->ai->openai->contentType[$type]) ? $this->config->ai->openai->contentType[$type] : $this->config->ai->openai->contentType[''];
|
||||
$requestHeaders = array();
|
||||
if(isset($this->config->ai->$modelType->api->$modelVendor->authFormat)) $requestHeaders[] = sprintf($this->config->ai->$modelType->api->$modelVendor->authFormat, $this->modelConfig->key);
|
||||
$requestHeaders[] = isset($this->config->ai->$modelType->contentType[$type]) ? $this->config->ai->$modelType->contentType[$type] : $this->config->ai->$modelType->contentType[''];
|
||||
|
||||
/* Assemble request url. */
|
||||
if($this->modelConfig->vendor == 'azure')
|
||||
if($modelType == 'openai')
|
||||
{
|
||||
$url = sprintf($this->config->ai->openai->api->azure->format, $this->config->ai->openai->api->azure->resource, $this->config->ai->openai->api->azure->deployment, $this->config->ai->openai->api->methods[$type], $this->config->ai->openai->api->azure->apiVersion);
|
||||
if($modelVendor == 'azure')
|
||||
{
|
||||
$url = sprintf($this->config->ai->openai->api->azure->format, $this->config->ai->openai->api->azure->resource, $this->config->ai->openai->api->azure->deployment, $this->config->ai->openai->api->methods[$type], $this->config->ai->openai->api->azure->apiVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = sprintf($this->config->ai->openai->api->openai->format, $this->config->ai->openai->api->openai->version, $this->config->ai->openai->api->methods[$type]);
|
||||
}
|
||||
}
|
||||
else
|
||||
elseif($modelType == 'ernie')
|
||||
{
|
||||
$url = sprintf($this->config->ai->openai->api->openai->format, $this->config->ai->openai->api->openai->version, $this->config->ai->openai->api->methods[$type]);
|
||||
$clientID = $this->modelConfig->key;
|
||||
$clientSecret = $this->modelConfig->secret;
|
||||
$authURL = sprintf($this->config->ai->ernie->api->$modelVendor->auth, $clientID, $clientSecret);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $authURL);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
$result = curl_exec($ch);
|
||||
if(!$result || curl_errno($ch))
|
||||
{
|
||||
$response = new stdclass();
|
||||
$response->result = 'fail';
|
||||
$response->message = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return $response;
|
||||
}
|
||||
$result = json_decode($result);
|
||||
if(json_last_error())
|
||||
{
|
||||
$response = new stdclass();
|
||||
$response->result = 'fail';
|
||||
$response->message = 'JSON decode error: ' . json_last_error_msg();
|
||||
curl_close($ch);
|
||||
return $response;
|
||||
}
|
||||
$accessToken = $result->access_token;
|
||||
|
||||
$url = sprintf($this->config->ai->ernie->api->$modelVendor->format, $accessToken);
|
||||
}
|
||||
|
||||
/* Set up requestor. */
|
||||
@@ -197,20 +236,22 @@ class aiModel extends model
|
||||
*/
|
||||
private function assembleRequestData($type, $data)
|
||||
{
|
||||
$modelType = $this->config->ai->models[$this->modelConfig->type];
|
||||
|
||||
$postData = new stdclass();
|
||||
$postData->model = $this->config->ai->openai->model->$type;
|
||||
$postData->model = $this->config->ai->$modelType->model->$type;
|
||||
|
||||
$data = static::standardizeParams($data);
|
||||
|
||||
/* Set required params, abort if missing. */
|
||||
foreach($this->config->ai->openai->params->$type->required as $param)
|
||||
foreach($this->config->ai->$modelType->params->$type->required as $param)
|
||||
{
|
||||
if(!isset($data->$param)) return false;
|
||||
$postData->$param = $data->$param;
|
||||
}
|
||||
|
||||
/* Set optional params. */
|
||||
foreach($this->config->ai->openai->params->$type->optional as $param)
|
||||
foreach($this->config->ai->$modelType->params->$type->optional as $param)
|
||||
{
|
||||
if(isset($data->$param)) $postData->$param = $data->$param;
|
||||
}
|
||||
@@ -293,12 +334,24 @@ class aiModel extends model
|
||||
$response = $this->decodeResponse($response);
|
||||
if(empty($response)) return false;
|
||||
|
||||
/* Extract chat message choices. */
|
||||
if(isset($response->choices) && count($response->choices) > 0)
|
||||
if($this->config->ai->models[$this->modelConfig->type] == 'ernie')
|
||||
{
|
||||
$messages = array();
|
||||
foreach($response->choices as $choice) $messages[] = $choice->message->content;
|
||||
return $messages;
|
||||
/* Extract chat message text. */
|
||||
if(!empty($response->result))
|
||||
{
|
||||
$messages = array($response->result);
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extract chat message choices. */
|
||||
if(isset($response->choices) && count($response->choices) > 0)
|
||||
{
|
||||
$messages = array();
|
||||
foreach($response->choices as $choice) $messages[] = $choice->message->content;
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -315,15 +368,24 @@ class aiModel extends model
|
||||
$response = $this->decodeResponse($response);
|
||||
if(empty($response)) return false;
|
||||
|
||||
/* Extract function call choices. */
|
||||
if(isset($response->choices) && count($response->choices) > 0)
|
||||
if($this->config->ai->models[$this->modelConfig->type] == 'ernie')
|
||||
{
|
||||
$arguments = array();
|
||||
foreach($response->choices as $choice)
|
||||
/* Extract function call arguments. */
|
||||
if(!empty($response->function_call)) return array($response->function_call->arguments);
|
||||
throw new AIResponseException('notFunctionCalling', $response);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extract function call choices. */
|
||||
if(isset($response->choices) && count($response->choices) > 0)
|
||||
{
|
||||
if(!empty($choice->message->function_call)) $arguments[] = $choice->message->function_call->arguments;
|
||||
$arguments = array();
|
||||
foreach($response->choices as $choice)
|
||||
{
|
||||
if(!empty($choice->message->function_call)) $arguments[] = $choice->message->function_call->arguments;
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
return $arguments;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -459,9 +521,55 @@ class aiModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of prompts.
|
||||
* Generate conversations with LLM for JSON output, but seperate the conversation into two parts.
|
||||
*
|
||||
* TODO: fully implement this.
|
||||
* Usage is the same as function `converseForJSON`, but this function will generate two conversations:
|
||||
* one for manipulating the natural language data, and the other for generating the JSON output.
|
||||
*
|
||||
* @param array $messages array of chat messages
|
||||
* @param object $schema schema of the output
|
||||
* @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())
|
||||
{
|
||||
/* First conversation. */
|
||||
$data = compact('messages');
|
||||
if(!empty($options))
|
||||
{
|
||||
foreach($options as $key => $value) $data[$key] = $value;
|
||||
}
|
||||
|
||||
$postData = $this->assembleRequestData('chat', $data);
|
||||
if(!$postData) return false;
|
||||
|
||||
$chatResponse = $this->makeRequest('chat', $postData);
|
||||
$chatMessages = $this->parseChatResponse($chatResponse);
|
||||
|
||||
$chatMessage = current($chatMessages);
|
||||
if(empty($chatMessage)) return false;
|
||||
|
||||
/* Second conversation for JSON output. */
|
||||
$messages = array_merge($this->lang->ai->engineeredPrompts->askForFunctionCalling, array((object)array('role' => 'user', 'content' => $chatMessage)));
|
||||
$functions = array((object)array('name' => 'function', 'description' => 'function', 'parameters' => $schema));
|
||||
|
||||
$data = compact('messages', 'functions');
|
||||
if(!empty($options))
|
||||
{
|
||||
foreach($options as $key => $value) $data[$key] = $value;
|
||||
}
|
||||
|
||||
$postData = $this->assembleRequestData('function', $data);
|
||||
if(!$postData) return false;
|
||||
|
||||
$response = $this->makeRequest('function', $postData);
|
||||
return $this->parseFunctionCallResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of prompts.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $status
|
||||
@@ -484,8 +592,6 @@ class aiModel extends model
|
||||
/**
|
||||
* Get prompt by id.
|
||||
*
|
||||
* TODO: fully implement this.
|
||||
*
|
||||
* @param int $id
|
||||
* @access public
|
||||
* @return object
|
||||
@@ -929,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)
|
||||
{
|
||||
@@ -946,7 +1053,7 @@ class aiModel extends model
|
||||
$schema = $this->getFunctionCallSchema($prompt->targetForm);
|
||||
if(empty($schema)) return -4;
|
||||
|
||||
$response = $this->converseForJSON(array((object)array('role' => 'user', 'content' => $wholePrompt)), $schema);
|
||||
$response = $this->{$this->config->ai->models[$this->modelConfig->type] == 'ernie' ? 'converseTwiceForJSON' : 'converseForJSON'}(array((object)array('role' => 'user', 'content' => $wholePrompt)), $schema);
|
||||
if(empty($response)) return -5;
|
||||
|
||||
return current($response);
|
||||
@@ -1624,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, '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->openaiVendorList) : $modelConfig->vendor;
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->vendorList->{empty($modelConfig->type) ? key($lang->ai->models->typeList) : $modelConfig->type}) : $modelConfig->vendor;
|
||||
$requiredFields = $config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
js::set('vendorList', $config->ai->vendorList);
|
||||
js::set('vendorListLang', $lang->ai->models->vendorList);
|
||||
?>
|
||||
<style>
|
||||
.required:after {right: -12px;}
|
||||
@@ -27,12 +28,16 @@ js::set('vendorList', $config->ai->vendorList);
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->models->vendor;?></th>
|
||||
<td><?php echo html::select('vendor', $lang->ai->models->openaiVendorList, $currentVendor, "class='form-control chosen' required");?></td>
|
||||
<td><?php echo html::select('vendor', $lang->ai->models->vendorList->{empty($modelConfig->type) ? key($lang->ai->models->typeList) : $modelConfig->type}, $currentVendor, "class='form-control chosen' required");?></td>
|
||||
</tr>
|
||||
<tr class="vendor-row <?php echo in_array('key', $requiredFields) ? '' : ' hidden'; ?>" data-vendor-field="key">
|
||||
<th><?php echo $lang->ai->models->key;?></th>
|
||||
<td><?php echo html::input('key', $modelConfig->key, "class='form-control' required");?></td>
|
||||
</tr>
|
||||
<tr class="vendor-row <?php echo in_array('secret', $requiredFields) ? '' : ' hidden'; ?>" data-vendor-field="secret">
|
||||
<th><?php echo $lang->ai->models->secret;?></th>
|
||||
<td><?php echo html::input('secret', $modelConfig->secret, "class='form-control' required");?></td>
|
||||
</tr>
|
||||
<tr class="vendor-row <?php echo in_array('resource', $requiredFields) ? '' : ' hidden'; ?>" data-vendor-field="resource">
|
||||
<th><?php echo $lang->ai->models->resource;?></th>
|
||||
<td><?php echo html::input('resource', empty($modelConfig->resource) ? '' : $modelConfig->resource, "class='form-control' required");?></td>
|
||||
@@ -77,21 +82,30 @@ js::set('vendorList', $config->ai->vendorList);
|
||||
</div>
|
||||
<script>
|
||||
$(function() {
|
||||
$('select[name="type"]').change(function()
|
||||
{
|
||||
var type = $(this).val();
|
||||
var vendorList = vendorListLang[type];
|
||||
$('select[name="vendor"]').html('');
|
||||
for(var vendor in vendorList) $('select[name="vendor"]').append('<option value="' + vendor + '">' + vendorList[vendor] + '</option>');
|
||||
$('select[name="vendor"]').trigger('chosen:updated');
|
||||
$('select[name="vendor"]').trigger('change');
|
||||
});
|
||||
$('select[name="vendor"]').change(function()
|
||||
{
|
||||
var vendor = $(this).val();
|
||||
var requiredFields = vendorList[vendor]['requiredFields'];
|
||||
$('.vendor-row').each(function()
|
||||
{
|
||||
var name = $(this).data('vendor-field');
|
||||
$(this).toggleClass('hidden', !requiredFields.includes(name));
|
||||
});
|
||||
});
|
||||
$('select[name="proxyType"]').change(function()
|
||||
{
|
||||
var proxyType = $(this).val();
|
||||
$('#proxyAddrContainer').toggle(proxyType != '');
|
||||
});
|
||||
$('select[name="vendor"]').change(function()
|
||||
{
|
||||
var vendor = $(this).val();
|
||||
var requiredFields = vendorList[vendor]['requiredFields'];
|
||||
$('.vendor-row').each(function()
|
||||
{
|
||||
var name = $(this).data('vendor-field');
|
||||
$(this).toggleClass('hidden', !requiredFields.includes(name));
|
||||
});
|
||||
});
|
||||
$('#mainForm').on('submit', function()
|
||||
{
|
||||
$('#testConn').attr('disabled', 'disabled');
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->openaiVendorList) : $modelConfig->vendor;
|
||||
$currentVendor = empty($modelConfig->vendor) ? key($lang->ai->models->vendorList->{empty($modelConfig->type) ? key($lang->ai->models->typeList) : $modelConfig->type}) : $modelConfig->vendor;
|
||||
$requiredFields = $config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
@@ -22,7 +22,7 @@ $requiredFields = $config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->models->vendor;?></th>
|
||||
<td><?php echo empty($modelConfig->vendor) ? $lang->ai->models->unconfigured : $lang->ai->models->openaiVendorList[$modelConfig->vendor]?></td>
|
||||
<td><?php echo (empty($modelConfig->vendor) || empty($modelConfig->type)) ? $lang->ai->models->unconfigured : $lang->ai->models->vendorList->{$modelConfig->type}[$modelConfig->vendor]?></td>
|
||||
</tr>
|
||||
<?php if(in_array('key', $requiredFields)): ?>
|
||||
<tr>
|
||||
@@ -30,6 +30,12 @@ $requiredFields = $config->ai->vendorList[$currentVendor]['requiredFields'];
|
||||
<td><?php echo empty($modelConfig->key) ? $lang->ai->models->unconfigured : ("<code title='{$lang->ai->models->concealTip}'>" . substr_replace($modelConfig->key, '...', 4, strlen($modelConfig->key) - 8) . '</code>'); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php if(in_array('secret', $requiredFields)): ?>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->models->secret; ?></th>
|
||||
<td><?php echo empty($modelConfig->secret) ? $lang->ai->models->unconfigured : ("<code title='{$lang->ai->models->concealTip}'>" . substr_replace($modelConfig->secret, '...', 4, strlen($modelConfig->secret) - 8) . '</code>'); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php if(in_array('resource', $requiredFields)): ?>
|
||||
<tr>
|
||||
<th><?php echo $lang->ai->models->resource; ?></th>
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-90px"><?php echo $lang->prompt->model; ?></th>
|
||||
<td><?php echo $lang->ai->models->typeList['openai-gpt35']; ?></td>
|
||||
<td><?php echo $lang->ai->prompts->modelNeutral; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user