HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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();
    }
}