Fix form AI creation bug + use gpt4 turbo with Json mode
This commit is contained in:
parent
28e55574e6
commit
381824183c
|
@ -227,11 +227,12 @@ class GenerateTemplate extends Command
|
||||||
->setAiModel('gpt-3.5-turbo-16k')
|
->setAiModel('gpt-3.5-turbo-16k')
|
||||||
->useStreaming()
|
->useStreaming()
|
||||||
->setSystemMessage('You are an assistant helping to generate forms.');
|
->setSystemMessage('You are an assistant helping to generate forms.');
|
||||||
$completer->completeChat([
|
$completer->expectsJson()->completeChat([
|
||||||
["role" => "user", "content" => Str::of(self::FORM_STRUCTURE_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString()]
|
["role" => "user", "content" => Str::of(self::FORM_STRUCTURE_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString()]
|
||||||
], 6000);
|
], 6000);
|
||||||
$formData = $completer->getArray();
|
$formData = $completer->getArray();
|
||||||
|
|
||||||
|
$completer->doesNotExpectJson();
|
||||||
$formDescriptionPrompt = Str::of(self::FORM_DESCRIPTION_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString();
|
$formDescriptionPrompt = Str::of(self::FORM_DESCRIPTION_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString();
|
||||||
$formShortDescription = $completer->completeChat([
|
$formShortDescription = $completer->completeChat([
|
||||||
["role" => "user", "content" => Str::of(self::FORM_SHORT_DESCRIPTION_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString()]
|
["role" => "user", "content" => Str::of(self::FORM_SHORT_DESCRIPTION_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString()]
|
||||||
|
@ -240,6 +241,7 @@ class GenerateTemplate extends Command
|
||||||
$formShortDescription = Str::of($formShortDescription)->replaceMatches('/^"(.*)"$/', '$1')->toString();
|
$formShortDescription = Str::of($formShortDescription)->replaceMatches('/^"(.*)"$/', '$1')->toString();
|
||||||
|
|
||||||
// Get industry & types
|
// Get industry & types
|
||||||
|
$completer->expectsJson();
|
||||||
$industry = $this->getIndustries($completer, $this->argument('prompt'));
|
$industry = $this->getIndustries($completer, $this->argument('prompt'));
|
||||||
$types = $this->getTypes($completer, $this->argument('prompt'));
|
$types = $this->getTypes($completer, $this->argument('prompt'));
|
||||||
|
|
||||||
|
@ -247,10 +249,12 @@ class GenerateTemplate extends Command
|
||||||
$relatedTemplates = $this->getRelatedTemplates($industry, $types);
|
$relatedTemplates = $this->getRelatedTemplates($industry, $types);
|
||||||
|
|
||||||
// Now get description and QAs
|
// Now get description and QAs
|
||||||
|
$completer->doesNotExpectJson();
|
||||||
$formDescription = $completer->completeChat([
|
$formDescription = $completer->completeChat([
|
||||||
["role" => "user", "content" => $formDescriptionPrompt]
|
["role" => "user", "content" => $formDescriptionPrompt]
|
||||||
])->getHtml();
|
])->getHtml();
|
||||||
|
|
||||||
|
$completer->expectsJson();
|
||||||
$formCoverKeywords = $completer->completeChat([
|
$formCoverKeywords = $completer->completeChat([
|
||||||
["role" => "user", "content" => $formDescriptionPrompt],
|
["role" => "user", "content" => $formDescriptionPrompt],
|
||||||
["role" => "assistant", "content" => $formDescription],
|
["role" => "assistant", "content" => $formDescription],
|
||||||
|
@ -263,6 +267,7 @@ class GenerateTemplate extends Command
|
||||||
["role" => "assistant", "content" => $formDescription],
|
["role" => "assistant", "content" => $formDescription],
|
||||||
["role" => "user", "content" => self::FORM_QAS_PROMPT]
|
["role" => "user", "content" => self::FORM_QAS_PROMPT]
|
||||||
])->getArray();
|
])->getArray();
|
||||||
|
$completer->doesNotExpectJson();
|
||||||
$formTitle = $completer->completeChat([
|
$formTitle = $completer->completeChat([
|
||||||
["role" => "user", "content" => $formDescriptionPrompt],
|
["role" => "user", "content" => $formDescriptionPrompt],
|
||||||
["role" => "assistant", "content" => $formDescription],
|
["role" => "assistant", "content" => $formDescription],
|
||||||
|
@ -306,7 +311,6 @@ class GenerateTemplate extends Command
|
||||||
private function getIndustries(GptCompleter $completer, string $formPrompt): array
|
private function getIndustries(GptCompleter $completer, string $formPrompt): array
|
||||||
{
|
{
|
||||||
$industriesString = Template::getAllIndustries()->pluck('slug')->join(', ');
|
$industriesString = Template::getAllIndustries()->pluck('slug')->join(', ');
|
||||||
|
|
||||||
return $completer->completeChat([
|
return $completer->completeChat([
|
||||||
["role" => "user", "content" => Str::of(self::FORM_INDUSTRY_PROMPT)
|
["role" => "user", "content" => Str::of(self::FORM_INDUSTRY_PROMPT)
|
||||||
->replace('[REPLACE]', $formPrompt)
|
->replace('[REPLACE]', $formPrompt)
|
||||||
|
@ -318,7 +322,6 @@ class GenerateTemplate extends Command
|
||||||
private function getTypes(GptCompleter $completer, string $formPrompt): array
|
private function getTypes(GptCompleter $completer, string $formPrompt): array
|
||||||
{
|
{
|
||||||
$typesString = Template::getAllTypes()->pluck('slug')->join(', ');
|
$typesString = Template::getAllTypes()->pluck('slug')->join(', ');
|
||||||
|
|
||||||
return $completer->completeChat([
|
return $completer->completeChat([
|
||||||
["role" => "user", "content" => Str::of(self::FORM_TYPES_PROMPT)
|
["role" => "user", "content" => Str::of(self::FORM_TYPES_PROMPT)
|
||||||
->replace('[REPLACE]', $formPrompt)
|
->replace('[REPLACE]', $formPrompt)
|
||||||
|
|
|
@ -39,7 +39,8 @@ class GenerateAiForm implements ShouldQueue
|
||||||
|
|
||||||
$completer = (new GptCompleter(config('services.openai.api_key')))
|
$completer = (new GptCompleter(config('services.openai.api_key')))
|
||||||
->useStreaming()
|
->useStreaming()
|
||||||
->setSystemMessage('You are a robot helping to generate forms.');
|
->setSystemMessage('You are a robot helping to generate forms.')
|
||||||
|
->expectsJson();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$completer->completeChat([
|
$completer->completeChat([
|
||||||
|
|
|
@ -14,13 +14,14 @@ use OpenAI\Exceptions\ErrorException;
|
||||||
*/
|
*/
|
||||||
class GptCompleter
|
class GptCompleter
|
||||||
{
|
{
|
||||||
const AI_MODEL = 'gpt-4';
|
const AI_MODEL = 'gpt-4-turbo-preview';
|
||||||
|
|
||||||
protected Client $openAi;
|
protected Client $openAi;
|
||||||
protected mixed $result;
|
protected mixed $result;
|
||||||
protected array $completionInput;
|
protected array $completionInput;
|
||||||
protected ?string $systemMessage;
|
protected ?string $systemMessage;
|
||||||
|
|
||||||
|
protected bool $expectsJson = false;
|
||||||
protected int $tokenUsed = 0;
|
protected int $tokenUsed = 0;
|
||||||
protected bool $useStreaming = false;
|
protected bool $useStreaming = false;
|
||||||
|
|
||||||
|
@ -47,8 +48,23 @@ class GptCompleter
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function completeChat(array $messages, int $maxTokens = 4096, float $temperature = 0.81): self
|
public function expectsJson(): self
|
||||||
{
|
{
|
||||||
|
$this->expectsJson = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doesNotExpectJson(): self
|
||||||
|
{
|
||||||
|
$this->expectsJson = false;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function completeChat(array $messages, int $maxTokens = 4096, float $temperature = 0.81, ?bool $exceptJson = null): self
|
||||||
|
{
|
||||||
|
if (!is_null($exceptJson)) {
|
||||||
|
$this->expectsJson = $exceptJson;
|
||||||
|
}
|
||||||
$this->computeChatCompletion($messages, $maxTokens, $temperature)
|
$this->computeChatCompletion($messages, $maxTokens, $temperature)
|
||||||
->queryCompletion();
|
->queryCompletion();
|
||||||
|
|
||||||
|
@ -129,6 +145,12 @@ class GptCompleter
|
||||||
'temperature' => $temperature
|
'temperature' => $temperature
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($this->expectsJson) {
|
||||||
|
$completionInput['response_format'] = [
|
||||||
|
'type' => 'json_object'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$this->completionInput = $completionInput;
|
$this->completionInput = $completionInput;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,14 +280,9 @@ export default {
|
||||||
form_slug: response.form.slug
|
form_slug: response.form.slug
|
||||||
})
|
})
|
||||||
this.displayFormModificationAlert(response)
|
this.displayFormModificationAlert(response)
|
||||||
useRouter().push({
|
useRouter().push({ name: 'forms-slug-show-share', params: { slug: this.createdFormSlug, new_form: response.users_first_form } })
|
||||||
name: 'forms-show',
|
|
||||||
params: {
|
|
||||||
slug: this.createdForm.slug,
|
|
||||||
new_form: response.users_first_form
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
|
console.error(error)
|
||||||
if (error.response && error.response.status === 422) {
|
if (error.response && error.response.status === 422) {
|
||||||
this.validationErrorResponse = error.response
|
this.validationErrorResponse = error.response
|
||||||
this.showValidationErrors()
|
this.showValidationErrors()
|
||||||
|
|
|
@ -64,7 +64,7 @@ export const useCrisp = () => {
|
||||||
|
|
||||||
function pushEvent(event, data = {}) {
|
function pushEvent(event, data = {}) {
|
||||||
if (!crisp) return
|
if (!crisp) return
|
||||||
crisp.pushEvent(event, data)
|
crisp.session.pushEvent(event, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSegments(segments, overwrite = false) {
|
function setSegments(segments, overwrite = false) {
|
||||||
|
|
Loading…
Reference in New Issue