config->getSystemValue($key); return empty($result) ? $default : $result; } public function get_response(string $message, array $history = []): string { $result = ''; if (empty($message)) { throw new \Exception('Empty message'); } $data = [ // 'max_tokens' => self::MAX_TOKENS, 'model' => $this->get_config_key(self::CONFIG_MODEL, self::DEFAULT_MODEL), 'function_call' => 'none', 'messages' => [ [ 'role' => 'system', 'content' => 'Ты ассистент с искусственным интелектом в системе F7cloud', ], ], ]; foreach ($history as $item) { if ( !empty($item['content']) && !empty($item['role']) && in_array($item['role'], self::ROLES) ) { $data['messages'][] = $item; } } $data['messages'][] = [ 'role' => 'user', 'content' => $message, ]; try { $response_data = $this->send_request('chat/completions', $data); foreach ($response_data['choices'] as $choice) { $result .= $choice['message']['content']; } } catch (\Exception $e) { throw new \Exception('GigaChat request error'); } return $result; } public function get_models(): array { return $this->send_request('models', [], false); } public function get_balance(): array { return $this->send_request('balance', [], false); } function send_request(string $function, array $data, bool $is_post = true): array { $client = $this->clientService->newClient(); $options = [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer ' . $this->get_access_token() ], 'verify' => false, ]; if (!empty($data)) { $options['headers']['Content-Type'] = 'application/json'; $options['body'] = json_encode($data); } if ($is_post) { $response = $client->post(self::METHOD_URL . $function, $options); } else { $response = $client->get(self::METHOD_URL . $function, $options); } $out = $response->getBody(); return json_decode($out, true) ?: []; } function get_access_token(): string { $token = ''; $token_file = $this->get_access_token_file(); $token_data = json_decode($token_file->getContent(), true); if ( empty($token_data['expires_at']) || (($token_data['expires_at'] / 1000) < time()) ) { $token = $this->refresh_token()['access_token']; } else { $token = $token_data['access_token']; } return $token; } public function get_access_token_file(): File { $app_data_folder_name = $this->rootFolder->getAppDataDirectoryName(); $app_data_folder = $this->rootFolder->get($app_data_folder_name); if (!$app_data_folder->nodeExists('/' . Application::APP_ID)) { $app_data_folder->newFolder('/' . Application::APP_ID); } $app_folder = $app_data_folder->get('/' . Application::APP_ID); if (!$app_folder->nodeExists(self::TOKEN_FILE)) { $app_folder->newFile(self::TOKEN_FILE); } return $app_folder->get(self::TOKEN_FILE); } function refresh_token(): array { $client = $this->clientService->newClient(); $response = $client->post(self::TOKEN_URL, [ 'body' => http_build_query(['scope' => $this->get_config_key(self::CONFIG_ACCESS_SCOPE)]), 'verify' => false, 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json', 'RqUID' => self::get_uuid4(), 'Authorization' => ' Basic ' . $this->get_config_key(self::CONFIG_ACCESS_KEY) ], ]); $out = $response->getBody(); $token_data = json_decode($out, true) ?: []; if (empty($token_data['access_token'])) { throw new \Exception('Empty access_token ' . $out); } $token_file = $this->get_access_token_file(); $token_file->putContent($out); return $token_data; } public static function get_uuid4(): string { $data = random_bytes(16); $data[6] = chr((ord($data[6]) & 0x0f) | 0x40); $data[8] = chr((ord($data[8]) & 0x3f) | 0x80); return vsprintf("%s%s-%s-%s-%s-%s%s%s", str_split(bin2hex($data), 4)); } }