File: /var/www/html/laravel/app/Models/Prompt.php
<?php
namespace App\Models;
use App\Prompts\Chat\SystemMessagePromptTemplate;
use App\Prompts\Chat\UserMessagePromptTemplate;
use Auth;
use DB;
use Illuminate\Database\Eloquent\Model;
use OpenAI;
/**
* @property $id integer
*/
class Prompt extends Model
{
protected $table = 'prompts';
protected $fillable = [
'prompt',
'json',
'is_active',
'example_ids',
'temperature',
'model',
'type'
];
public function processFiles(array $filePaths)
{
$notams = [];
foreach ($filePaths as $filePath) {
$fileContent = file_get_contents($filePath);
$fileContent = trim($fileContent);
try {
$fileContent = json_decode($fileContent);
} catch (\Exception $e) {
throw new \Exception('Невалидный JSON');
}
if (is_array($fileContent)) {
foreach ($fileContent as $notam) {
$notams[] = $notam;
}
} else {
$notams[] = $fileContent;
}
}
$notamsArray = $this->processNotams($notams);
return $notamsArray;
}
public function processNotams($notams, $input = [])
{
$notamsArray = [];
$batchId = Notam::select(DB::raw('MAX(batch_id) as batch_id'))->pluck('batch_id')->toArray();
if (!empty($batchId)) {
$batchId = array_shift($batchId);
}
if (empty($input['offset'])) { // If offset not empty - we continue previous batch
$batchId = $batchId + 1;
}
if (!$batchId) {
$batchId = 1;
}
$exampleIds = [];
if ($this->example_ids) {
$exampleIds = explode(',', $this->example_ids);
$examples = Notam::query()->whereIn('id', $exampleIds)->get();
foreach ($examples as $example) {
$messages[] = ['role' => 'user', 'content' => $example->input];
$messages[] = ['role' => 'assistant', 'content' => $example->correct_response];
}
}
$batchTexts = [];
$miniBatchNotams = [];
// $notams array of notams
foreach ($notams as $notamInput) {
if (!is_string($notamInput)) {
$notamInput = json_encode($notamInput);
}
$hash = Notam::hash($notamInput);
$notam = new Notam([
'input' => $notamInput,
'batch_id' => $batchId,
'output' => '',
'chatgpt_response' => '',
'prompt_tokens' => 0,
'completion_tokens' => 0,
'total_tokens' => 0,
'prompt_id' => $this->id,
'example_ids' => implode(',', $exampleIds),
'user_id' => \Auth::user()->id,
'request_hash' => $hash,
'correct_response' => Notam::getValidResponse($hash),
]);
$notam->save();
$miniBatchNotams[] = $notam;
$batchTexts[] = $notam->getText();
if (count($batchTexts) == 1) {
$this->processBatch($miniBatchNotams, $batchTexts, $notamsArray);
$batchTexts = [];
$miniBatchNotams = [];
}
}
if (count($batchTexts)) {
$this->processBatch($miniBatchNotams, $batchTexts, $notamsArray);
}
$notamsArray = Notam::where('batch_id', $batchId)->get()->toArray();
return $notamsArray;
}
public function getTuningData($lastJobDate = null, $maxExamples = 0, $skipExamples = 0)
{
$fineTuningExamples = [];
if ($this->type == 'mel') {
$approvedExamples = Mel::where('fine_tuning', 1)
->where('correct_response', 'like', "%\"CheckNeeded\":false%");
} elseif ($this->type == 'notam') {
$approvedExamples = Notam::where('fine_tuning', 1)
->where('gpt41_correct_response', 'like', "%\"CheckNeeded\":false%");
} elseif ($this->type == 'aip') {
$approvedExamples = Aip::whereNotNull('correct_response');
}
if ($lastJobDate !== null) {
$approvedExamples->where('updated_at', '>', $lastJobDate);
}
if ($maxExamples > 0) {
$approvedExamples->limit($maxExamples);
if ($skipExamples !== 0) {
$approvedExamples = $approvedExamples->skip($skipExamples);
}
}
$approvedExamples = $approvedExamples->get();
foreach ($approvedExamples as $example) {
if ($example->correct_response) {
$fineTuningData = [];
$messages = [];
$messages[] = [
'role' => 'system',
'content' => $this->prompt
];
$messages[] = [
'role' => 'user',
'content' => $example->getText()
];
if ($this->type == 'mel') {
$messages[] = [
'role' => 'assistant',
'content' => $example->gpt41_correct_response
];
} else {
$messages[] = [
'role' => 'assistant',
'content' => $example->minifyJson($example->gpt41_correct_response)
];
}
$fineTuningData['messages'] = $messages;
$fineTuningExamples[] = json_encode($fineTuningData, JSON_UNESCAPED_UNICODE);
}
}
return $fineTuningExamples;
}
public function getTuningDataCount($lastJobDate = null)
{
if ($this->type == 'mel') {
$approvedExamples = Mel::where('fine_tuning', 1)
->where('correct_response', 'like', "%\"CheckNeeded\":false%");
} elseif($this->type == 'notam') {
$approvedExamples = Notam::query()
->whereNotNull('gpt41_correct_response')
->where('fine_tuning', 1);
} elseif($this->type == 'aip') {
$approvedExamples = Aip::whereNotNull('correct_response');
}
if ($lastJobDate !== null) {
$approvedExamples->where('updated_at', '>', $lastJobDate);
}
return $approvedExamples->count();
}
public function getFineTuningJobs()
{
return FineTuningJob::where('prompt_id', $this->id)->orderBy('created_at', 'desc')->get();
}
}